mirror of
https://github.com/chubin/cheat.sh.git
synced 2024-12-02 07:50:04 +03:00
Make cht.sh work under POSIX environment.
There are a few corner cases still, but normal desktop users should be satisfied on almost any *nix now. Verified with bash, ksh (OpenBSD) and dash.
This commit is contained in:
parent
5d56fca13e
commit
c67fb61662
126
share/cht.sh.txt
126
share/cht.sh.txt
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/bin/sh
|
||||
#
|
||||
# [X] open section
|
||||
# [X] one shot mode
|
||||
@ -8,7 +8,7 @@
|
||||
# [X] yank/y/copy/c
|
||||
# [X] Y/C
|
||||
# [X] eof problem
|
||||
# [X] less
|
||||
# [X] more
|
||||
# [X] stealth mode
|
||||
#
|
||||
# here are several examples for the stealth mode:
|
||||
@ -38,30 +38,30 @@ get_query_options()
|
||||
{
|
||||
local query="$*"
|
||||
if [ -n "$CHTSH_QUERY_OPTIONS" ]; then
|
||||
if [[ $query == *\?* ]]; then
|
||||
query="$query&${CHTSH_QUERY_OPTIONS}"
|
||||
else
|
||||
query="$query?${CHTSH_QUERY_OPTIONS}"
|
||||
fi
|
||||
case $query in
|
||||
*\?*) query="$query&${CHTSH_QUERY_OPTIONS}";;
|
||||
*) query="$query?${CHTSH_QUERY_OPTIONS}";;
|
||||
esac
|
||||
fi
|
||||
echo "$query"
|
||||
printf "%s" "$query"
|
||||
}
|
||||
|
||||
do_query()
|
||||
{
|
||||
local query="$*"
|
||||
local b_opts=()
|
||||
local b_opts=
|
||||
local uri="https://cht.sh/\"\$(get_query_options $query)\""
|
||||
|
||||
if [ -e "$HOME/.cht.sh/id" ]; then
|
||||
b_opts=(-b "$HOME/.cht.sh/id")
|
||||
b_opts="-b \"\$HOME/.cht.sh/id\""
|
||||
fi
|
||||
|
||||
curl "${b_opts[@]}" -s https://cht.sh/"$(get_query_options $query)" > "$TMP1"
|
||||
eval curl $b_opts -s $uri > "$TMP1"
|
||||
|
||||
if [ -z "$lines" ] || [ "$(wc -l "$TMP1" | awk '{print $1}')" -lt "$lines" ]; then
|
||||
cat "$TMP1"
|
||||
else
|
||||
less -R "$TMP1"
|
||||
${PAGER:-$defpager} "$TMP1"
|
||||
fi
|
||||
}
|
||||
|
||||
@ -69,17 +69,17 @@ prepare_query()
|
||||
{
|
||||
local section="$1"; shift
|
||||
local input="$1"; shift
|
||||
local arguments="$1"; shift
|
||||
local arguments="$1"
|
||||
|
||||
local query
|
||||
if [ -z "$section" ] || [[ "$input" = /* ]]; then
|
||||
query=$(echo "$input" | sed 's@ @/@; s@ @+@g')
|
||||
if [ -z "$section" ] || [ x"${input}" != x"${input#/}" ]; then
|
||||
query=$(printf %s "$input" | sed 's@ @/@; s@ @+@g')
|
||||
else
|
||||
query=$(echo "$section/$input" | sed 's@ @+@g')
|
||||
query=$(printf %s "$section/$input" | sed 's@ @+@g')
|
||||
fi
|
||||
|
||||
[ -n "$arguments" ] && arguments="?$arguments"
|
||||
echo "$query$arguments"
|
||||
printf %s "$query$arguments"
|
||||
}
|
||||
|
||||
get_list_of_sections()
|
||||
@ -87,16 +87,41 @@ get_list_of_sections()
|
||||
curl -s https://cht.sh/:list | grep -v '/.*/' | grep '/$'
|
||||
}
|
||||
|
||||
gen_random_str()
|
||||
(
|
||||
len=$1
|
||||
if command -v openssl >/dev/null; then
|
||||
openssl rand -base64 $(($len*3/4)) | awk -v ORS='' //
|
||||
else
|
||||
rdev=/dev/urandom
|
||||
for d in /dev/{srandom,random,arandom}; do
|
||||
test -r $d && rdev=$d
|
||||
done
|
||||
if command -v hexdump >/dev/null; then
|
||||
hexdump -vn $(($len/2)) -e '1/1 "%02X" 1 ""' $rdev
|
||||
elif command -v xxd >/dev/null; then
|
||||
xxd -l $(($len/2)) -ps $dev | awk -v ORS='' //
|
||||
else
|
||||
cd /tmp
|
||||
s=
|
||||
while [ $(echo "$s" | wc -c) -lt $len ]; do
|
||||
s="$s$(mktemp -u XXXXXXXXXX)"
|
||||
done
|
||||
printf %.${len}s "$s"
|
||||
fi
|
||||
fi
|
||||
)
|
||||
|
||||
if [ -e "$HOME"/.cht.sh/cht.sh.conf ]; then
|
||||
# shellcheck disable=SC1090,SC2002
|
||||
source <( cat "$HOME"/.cht.sh/cht.sh.conf | sed 's/#.*//' | grep -xv '' | sed s/^/CHTSH_/ ) >& /dev/null
|
||||
. "$HOME"/.cht.sh/cht.sh.conf
|
||||
fi
|
||||
|
||||
if [ "$1" == --read ]; then
|
||||
if [ "$1" = --read ]; then
|
||||
read -r a || a=exit
|
||||
echo $a
|
||||
printf "%s\n" "$a"
|
||||
exit 0
|
||||
elif [ "$1" == --help ] || [ -z "$1" ]; then
|
||||
elif [ x"$1" = x--help ] || [ -z "$1" ]; then
|
||||
cat <<EOF
|
||||
Usage:
|
||||
|
||||
@ -105,7 +130,7 @@ Usage:
|
||||
${0##*/} QUERY process QUERY and exit
|
||||
EOF
|
||||
exit 0
|
||||
elif [ "$1" == --shell ]; then
|
||||
elif [ x"$1" = x--shell ]; then
|
||||
shell_mode=yes
|
||||
shift
|
||||
fi
|
||||
@ -116,7 +141,7 @@ prompt="cht.sh"
|
||||
opts=""
|
||||
input=""
|
||||
for o; do
|
||||
if [[ "$o" == -* ]]; then
|
||||
if [ x"$o" != x"${o#-}" ]; then
|
||||
opts="${opts}${o#-}"
|
||||
else
|
||||
input="$input $o"
|
||||
@ -129,10 +154,10 @@ if [ "$shell_mode" != yes ]; then
|
||||
exit 0
|
||||
else
|
||||
new_section="$1"
|
||||
valid_sections=($(get_list_of_sections))
|
||||
valid=no; for q in "${valid_sections[@]}"; do [[ "$q" == $new_section/ ]] && { valid=yes; break; }; done
|
||||
valid_sections=$(get_list_of_sections)
|
||||
valid=no; for q in $valid_sections; do [ "$q" = "$new_section/" ] && { valid=yes; break; }; done
|
||||
|
||||
if [[ $valid = yes ]]; then
|
||||
if [ "$valid" = yes ]; then
|
||||
section="$new_section"
|
||||
this_query="$(echo "$input" | sed 's@ *[^ ]* *@@')"
|
||||
this_prompt="\033[0;32mcht.sh/$section>\033[0m "
|
||||
@ -147,14 +172,22 @@ else
|
||||
fi
|
||||
|
||||
if [ "$is_macos" != yes ]; then
|
||||
which xsel >& /dev/null || { echo 'DEPENDENCY: please install "xsel" for "copy"' >&2; }
|
||||
command -v xsel >/dev/null || echo 'DEPENDENCY: please install "xsel" for "copy"' >&2
|
||||
fi
|
||||
which rlwrap >& /dev/null || { echo 'DEPENDENCY: install "rlwrap" to use cht.sh in the shell mode' >&2; exit 1; }
|
||||
which curl >& /dev/null || { echo 'DEPENDENCY: install "curl" to use cht.sh' >&2; exit 1; }
|
||||
command -v rlwrap >/dev/null || { echo 'DEPENDENCY: install "rlwrap" to use cht.sh in the shell mode' >&2; exit 1; }
|
||||
command -v curl >/dev/null || { echo 'DEPENDENCY: install "curl" to use cht.sh' >&2; exit 1; }
|
||||
|
||||
mkdir -p "$HOME/.cht.sh/"
|
||||
lines=$(tput lines)
|
||||
|
||||
if command -v less >/dev/null; then
|
||||
defpager="less -R"
|
||||
elif command -v more >/dev/null; then
|
||||
defpager=more
|
||||
else
|
||||
defpager=cat
|
||||
fi
|
||||
|
||||
TMP1=$(mktemp /tmp/cht.sh.XXXXXXXXXXXXX)
|
||||
trap 'rm -f $TMP1 $TMP2' EXIT
|
||||
trap 'true' INT
|
||||
@ -171,7 +204,7 @@ while true; do
|
||||
fi
|
||||
|
||||
input=$(
|
||||
rlwrap -H $HOME/.cht.sh/history -pgreen -C cht.sh -S "$full_prompt" bash "$0" --read | sed 's/ *#.*//'
|
||||
rlwrap -H "$HOME/.cht.sh/history" -pgreen -C cht.sh -S "$full_prompt" sh "$0" --read | sed 's/ *#.*//'
|
||||
)
|
||||
|
||||
case "$input" in
|
||||
@ -204,12 +237,12 @@ EOF
|
||||
continue
|
||||
;;
|
||||
"cd "*)
|
||||
new_section=$(echo "$input" | sed 's/cd //; s/ .*//; s@/\+$@@; s@^/\+@@')
|
||||
if [ "$new_section" = "" ] || [ "$new_section" = ".." ] || [ "$new_section" = / ]; then
|
||||
new_section=$(echo "$input" | sed 's/cd *//; s@/*$@@; s@^/*@@')
|
||||
if [ -z "$new_section" ] || [ ".." = "$new_section" ]; then
|
||||
section=""
|
||||
else
|
||||
valid_sections=($(get_list_of_sections))
|
||||
valid=no; for q in "${valid_sections[@]}"; do [[ "$q" == $new_section/ ]] && { valid=yes; break; }; done
|
||||
valid_sections=$(get_list_of_sections)
|
||||
valid=no; for q in $valid_sections; do [ "$q" = "$new_section/" ] && { valid=yes; break; }; done
|
||||
if [ "$valid" = no ]; then
|
||||
echo "Invalid section: $new_section"
|
||||
echo "Valid sections:"
|
||||
@ -265,20 +298,20 @@ EOF
|
||||
id|"id "*)
|
||||
id_file="$HOME/.cht.sh/id"
|
||||
|
||||
if [ "$input" = id ]; then
|
||||
if [ id = "$input" ]; then
|
||||
new_id=""
|
||||
else
|
||||
new_id=$(echo "$input" | sed 's/id \+//; s/ *$//; s/ /+/g')
|
||||
new_id=$(echo "$input" | sed 's/id *//; s/ *$//; s/ /+/g')
|
||||
fi
|
||||
if [ "$new_id" = remove ]; then
|
||||
if [ -e "$id_file" ]; then
|
||||
rm -f "$id_file" && echo "id is removed"
|
||||
rm -f -- "$id_file" && echo "id is removed"
|
||||
else
|
||||
echo "id was not set, so you can't remove it"
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
if [ -n "$new_id" ] && [ "$new_id" != reset ] && [ "$(echo $new_id | wc -c)" -lt 16 ]; then
|
||||
if [ -n "$new_id" ] && [ reset != "$new_id" ] && [ $(/bin/echo -n "$new_id" | wc -c) -lt 16 ]; then
|
||||
echo "ERROR: $new_id: Too short id. Minimal id length is 16. Use 'id reset' for a random id"
|
||||
continue
|
||||
fi
|
||||
@ -287,19 +320,19 @@ EOF
|
||||
# if yes, just show it
|
||||
# if not, generate a new id
|
||||
if [ -e "$id_file" ]; then
|
||||
echo $(cat "$id_file" | awk '{if ($6 == "id") print $NF}' | head -1)
|
||||
echo $(awk '$6 == "id" {print $NF}' <"$id_file" | tail -n 1)
|
||||
continue
|
||||
else
|
||||
new_id=reset
|
||||
fi
|
||||
fi
|
||||
if [ "$new_id" = reset ]; then
|
||||
new_id="$(cat /dev/urandom 2> /dev/null | env LC_CTYPE=C tr -cd 'a-f0-9' 2> /dev/null | head -c 32)"
|
||||
new_id=$(gen_random_str 12)
|
||||
else
|
||||
echo WARNING: if someone gueses your id, he can read your cht.sh search history
|
||||
fi
|
||||
if [ -e "$id_file" ] && grep -q '\tid\t[^\t]\+$' "$id_file" 2> /dev/null; then
|
||||
sed -i 's/\tid\t[^\t]\+$/ id '"$new_id"'/' "$id_file"
|
||||
if [ -e "$id_file" ] && grep -q '\tid\t[^\t][^\t]*$' "$id_file" 2> /dev/null; then
|
||||
sed -i 's/\tid\t[^\t][^\t]*$/ id '"$new_id"'/' "$id_file"
|
||||
else
|
||||
if ! [ -e "$id_file" ]; then
|
||||
printf '#\n\n' > "$id_file"
|
||||
@ -354,9 +387,9 @@ EOF
|
||||
curl -s https://cht.sh/:cht.sh > "$TMP2"
|
||||
if ! cmp "$0" "$TMP2" > /dev/null 2>&1; then
|
||||
if grep -q ^__CHTSH_VERSION= "$TMP2"; then
|
||||
args=(--shell)
|
||||
[ -n "$section" ] && args=("${args[@]}" "$section")
|
||||
cp "$TMP2" "$0" && echo "Updated. Restarting..." && rm "$TMP2" && CHEATSH_RESTART=1 exec "$0" "${args[@]}"
|
||||
# section was vaildated by us already
|
||||
args="--shell $section"
|
||||
cp "$TMP2" "$0" && echo "Updated. Restarting..." && rm "$TMP2" && CHEATSH_RESTART=1 exec "$0" $args
|
||||
else
|
||||
echo "Something went wrong. Please update manually"
|
||||
fi
|
||||
@ -367,7 +400,8 @@ EOF
|
||||
continue
|
||||
;;
|
||||
version)
|
||||
echo "cht.sh version $__CHTSH_VERSION of $__CHTSH_DATETIME; installed at: $(stat -c %y "$0" | sed 's@\..* @ @')"
|
||||
insttime=$(ls -lT -- "$0" | sed 's/ / /g' | cut -d ' ' -f 6-9)
|
||||
echo "cht.sh version $__CHTSH_VERSION of $__CHTSH_DATETIME; installed at: $insttime"
|
||||
TMP2=$(mktemp /tmp/cht.sh.XXXXXXXXXXXXX)
|
||||
if curl -s https://cht.sh/:cht.sh > "$TMP2"; then
|
||||
if ! cmp "$0" "$TMP2" > /dev/null 2>&1; then
|
||||
|
Loading…
Reference in New Issue
Block a user