0

I'm looking for a way to do quick calculations in the terminal (using utilities available in Ubuntu minimal) and get accurate fail errors when the math syntax is incorrect, eg: cli-calculator "foo+bar" || echo invalid math syntax

Some of the inputs would be:

  • 1+1 #should print 2 and return a 0 code

  • 5/2 #should print 2.5 and return a 0 code

  • 1/0 #should return a non 0 code

  • foo+bar #should return a non 0 code

I've tried bc, shell integrated arithmetic, expr, awk, perl and python but so far none has satisfied fully my requirements, so I'm looking for alternatives, follow use cases:

  • bc, it's able to do operations with float numbers but doesn't return error codes on invalid syntax input

    $ echo "1/0" | bc -l && echo all is fine || echo math syntax error
    Runtime error (func=(main), adr=3): Divide by zero
    all is fine
    $ echo "foo+bar" | bc -l && echo all is fine || echo math syntax error
    0 #should return an error
    all is fine
    
  • Shell integrated arithmetic and expr, don't support operations with float numbers and return valid codes on invalid math input

    $ echo $((5/2))
    2 #should return 2.5
    $ echo $((foo+bar))
    0 #should return an error
    $ expr 5 / 2
    2 #should return 2.5
    $ expr foo+bar
    foo+bar #should return an error
    
  • awk|perl, don't return invalid status codes on invalid math input.

    $ awk "BEGIN {print foo+bar; exit}"
    0 #should return a non 0 number and probably output an error
    $ echo "foo+bar" | perl -ple '$_=eval'
    0 #should return a non 0 number and probably output an error
    
  • python, supports float arithmetic operations and return status errors on invalid math syntax but it's slow.

    $ python -c 'from __future__ import division; from math import *; print(foo+bar)' && echo all fine || echo math syntax error
    NameError: name 'foo' is not defined
    math syntax error #good!
    $ python -c 'from __future__ import division; from math import *; print(5/2)' && echo all fine || echo math syntax error
    2.5` #good!
    all fine
    

Any ideas?

2
  • "echo $((5/2)) 2 #should return 2.5" No it should not. "echo scale=1; (5/2) | bc" should return 2.5
    – Rinzwind
    Nov 3, 2015 at 7:42
  • 1
    You say most of them fail. But they don't. Each of them work as described in the man page. You have to tell each tool what you want it do, in it's terms. They cannot read your mind.
    – andy256
    Feb 16, 2016 at 23:06

2 Answers 2

3

What about calc

sudo apt-get install apcalc

Examples

% calc 1/0  
    Error 10001

% calc foo + bar
"foo" is undefined
Error in commands

% calc 5/2
    2.5

Or qalc

% qalc 1/0
error: Division by zero.
1 / 0 = 1 / 0

% qalc foo + bar
error: "foo" is not a valid variable/function/unit.
0 + bar = 1 bar

% qalc 5/2      
5 / 2 = 2.5

bc

echo "1/0" | bc  
Runtime error (func=(main), adr=3): Divide by zero

echo "scale=1; 5/2" | bc
2.5

And this is correct, 0 + 0 is 0

% echo "foo+bar" | bc
0

Or gcalccmd, the console version of gnome-calculator the calculator of the GNOME desktop environment.

Examples

% gcalccmd    
> 1/0
Error (null)
> foo + bar
Error 3
> 5/2
2,5

Note that gcalccmd does not have readline support, so only the most basic line editing features are available. (Backspace works, but left/right keys don't)

1

Octave is another alternative. It is a very powerful free tool with a syntax 'like the commercial tool matlab'. If you want to run it without a gui, use the option --no-gui or the command octave-cli.

sudo apt-get install octave octave-info

Example based on your 'valid and invalid' expressions:

$ octave --no-gui
GNU Octave, version 4.0.0
Copyright (C) 2015 John W. Eaton and others.
This is free software; see the source code for copying conditions.
There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  For details, type 'warranty'.

Octave was configured for "i686-pc-linux-gnu".

Additional information about Octave is available at http://www.octave.org.

Please contribute if you find this software useful.
For more information, visit http://www.octave.org/get-involved.html

Read http://www.octave.org/bugs.html to learn how to submit bug reports.
For information about changes from previous versions, type 'news'.

>> 1+1 #valid
ans =  2
>> 5/2 #valid
ans =  2.5000
>> 1/0 #invalid
warning: division by zero
ans = Inf
>> foo+bar #invalid
error: 'foo' undefined near line 1 column 1
>> foo=1;bar=2  # assign values to foo and bar
bar =  2
>> foo+bar #now valid
ans =  3
>> 

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .