Shell Calculator
They say that old habits die hard, and the following is probably an example of such.
When I was 12 I bought a Commodore 64 which OS was a BASIC interpreter. One of the commands was print
, and if given an arithmic expression, it’d print the result of this expression. Since the print command was typed a lot, one could use a question mark as short-hand.
Since my computer was always on and nearby, I used it as a calculator, typing e.g. ? 7.45*39
.
When I was 14 I bought an Amiga, and it was only natural to create an alias for evaluating expressions on ?
.
Today I have a Mac, and recently switched to zsh. I’ve previously done a similar alias/function for tcsh and bash, so today I figured it was time to do it for zsh.
Actually turned out to be rather simple:
alias '?=bc -l <<<'
With zsh, aliases are expanded first, so when writing:
? (546-425)*34
It’ll expand to:
bc -l <<< (546-425)*34
The <<<
says the next part is a here-string, which is a string that is given to the command as standard input, so this is equivalent to writing:
echo '(546-425)*34' | bc -l
Notice however that in this form, we need to quote the expression, since the parenthesis and asterisk would otherwise cause a syntax error. But with here-strings all characters are taken verbatim (which is to our advantage).
The only limitation with this solution is that we cannot have any spaces in our expression. E.g. ? 42 / 7
would fail.
There is however one thing that bothers me. If you perform e.g. ? 42/7
then it’ll output:
6.00000000000000000000
To fix that we’d need to post-process the output from bc
, unfortunately the alias system in zsh doesn’t support arguments, making it impossible to put anything after our arithmetic expression.
We can however wrap bc
in a function that does the post-processing and then let our alias call that function instead, and that’s what I ended up doing, so I have the following two lines in my .zshrc
:
eval_helper () { bc -l|perl -pe 's/(\.[^0]+)0+$|\.0+$/$1/'; }
alias '?=eval_helper <<<'