Skip to content

Instantly share code, notes, and snippets.

@osher
Last active January 16, 2026 03:40
Show Gist options
  • Select an option

  • Save osher/39931471f2f0cd54b59bde49f0e314e5 to your computer and use it in GitHub Desktop.

Select an option

Save osher/39931471f2f0cd54b59bde49f0e314e5 to your computer and use it in GitHub Desktop.
#-----------------------------------------------
# shell calculator
#-----------------------------------------------
function calc() { # use `calc <expr>` in your shell
local EXPR="$*";
case "$EXPR" in
--help|help|--h|h) echo "Synopsis: calc <expression>|mc|help
Calculator with last-result memrory based on shell arithmetics.
Start with an operator to use last result as 1st operand, and/or use MR anywhere in your expression as an operand).
Supported operators by order of operations:
(https://www.gnu.org/software/bash/manual/html_node/Shell-Arithmetic.html).
Convenience sinonyms that rid you of quoting special shell characters in your expression:
multiplication * x X xx XX
exponentiation ** ^ (power is more common than XOR, see below for XOR)
bitwise AND &
bitwise OR | or
bitwise XOR ^^ ~^ xor XOR
bitwise NOT ~ not
left shift << ls lsift
right shift >> rs rshift
Memory Clear MC C Clear \"Memory Clear\"
help --help -h help h
" && return;;
C|c|MC|mc|Clear|clear|"Memory Clear") _CALC_MEMORY=0 && echo "\t(memory cleared)" && return ;;
esac
[[ "$EXPR" =~ '^(\(|\+|\-|\*|x|X|xx|XX|\*\*|/|%|<<|ls|lshift|>>|rs|rshift|&|or|OR|xor|XOR|\||\^|~)' ]] && EXPR="$_CALC_MEMORY $EXPR";
local OUT=$'\033[36m'"${EXPR}"$'\033[0m';
MR=_CALC_MEMORY local RESULT=$(_calc "$EXPR" 2>&1);
[[ "$RESULT" =~ "bad math expression" ]] && echo $'\033[31mBad math expression:\033[0m '"$OUT"'\n\t'"${RESULT#*bad math expression:}" && return 1;
_CALC_MEMORY=$RESULT;
OUT+=$'\t= \033[32m'$_CALC_MEMORY$'\033[0m';
local PLAIN=$(echo -e "$OUT" | sed 's/\x1b\[[0-9;]*m//g');
local WIDTH=$(tput cols 2>/dev/null || echo 80);
local PAD=$(( (WIDTH - ${#PLAIN}) / 2 ));
printf "%*s%s\n" $PAD "" "$OUT";
}
function _calc() { # use `$(_calc <expr> )` in your scripts with just the convinience operators
local EXPR="$*";
EXPR=$(echo "$EXPR" \
| sed -r 's/\b(x|X|xx|XX)\b/*/g; s/\b(\^\^|~\^|xor|XOR)\b/\^/g; s/or/|/g; s/not/~/g; s/\^/**/g; s/(ls|lshift)/<</g; s/(rs|rshift)/>>/g');
echo $(( $EXPR ));
}
@osher
Copy link
Author

osher commented Jan 16, 2026

I use it as ~/.oh-my-zsh/custom/calc.zsh

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