Skip to content

Instantly share code, notes, and snippets.

@thingsiplay
Last active May 6, 2025 06:50
Show Gist options
  • Save thingsiplay/69aada6a57f829d9580d7b54f8a207a0 to your computer and use it in GitHub Desktop.
Save thingsiplay/69aada6a57f829d9580d7b54f8a207a0 to your computer and use it in GitHub Desktop.
cheat.sh - The only cheat sheet you need
#!/usr/bin/env bash
cheat='curl -s cheat.sh'
menu='fzf --reverse'
pager='less -R -c'
cachefile_max_age_hours=6
explain='https://explainshell.com/explain?cmd'
# Path to temporary cache file. If your Linux system does not support /dev/shm
# or if you are on MacOS, then change the path to your liking:
cachefile='/dev/shm/cheatlist' # GNU+LINUX
# cachefile="${TMPDIR}/cheatlist" # MacOS/Darwin
# Download list file and cache it.
listing() {
if [ -f "${cachefile}" ]; then
local filedate
local now
local age_hours
filedate=$(stat -c %Y -- "${cachefile}")
now=$(date +%s)
age_hours=$(((now - filedate) / 60 / 60))
if [[ "${age_hours}" -gt "${cachefile_max_age_hours}" ]]; then
${cheat}/:list >"${cachefile}"
fi
else
${cheat}/:list >"${cachefile}"
fi
cat -- "${cachefile}"
}
if [[ "${#}" -gt 1 ]]; then
cmd="${*}"
program_name="${1/ */}"
else
cmd=""
program_name="${1}"
fi
case "${program_name}" in
'')
if selection=$(listing | ${menu}); then
output="$(${cheat}/"${selection}")"
echo "${output}" | ${pager}
echo "${output}"
fi
;;
'-h')
# ${cheat}/:help | ${pager}
${cheat}/:help
;;
'-l')
listing
;;
*)
# ${cheat}/"${*}" | ${pager}
${cheat}/"${program_name}"
;;
esac
if [[ "${#}" -gt 1 ]]; then
normal='\e[0m'
whitegrey='\e[37;100m'
echo -e "\n${whitegrey} explainshell:${cmd} ${normal}"
w3m -dump "${explain}=${cmd}" | sed '1,9d' | grep -v '^ • ' | cat -s
fi
@nidan841g
Copy link

This case statement would allow the script to work on MacOS as well as Linux.

case "$(uname -o)" in
    GNU/Linux)  cachefile='/dev/shm/cheatlist'  ;;
    Darwin)     cachefile="$TMPDIR/cheatlist" ;;
    *)          echo "Unsupported OS"; exit 1 ;;
esac

@thingsiplay
Copy link
Author

Thank you for the suggestion. I actually would like to avoid additional checks that are always true for the current user. The variables are intended to be changed for the environment and user needs, like an option. So I will add a comment and a line ready to uncomment instead. I prefer this approach. I hope this is a good enough compromise.

@thingsiplay
Copy link
Author

Updated with additional output from https://explainshell.com, if the requested command is more than just the name of the application. The output is interpreted by terminal browser w3m and therefore is required. This is only used if the request includes any options like:

grep -v

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment