Question

I was looking for a simple command line calculator and found calc to be simple and useful and it turns out it is installed on our server.

This is the site for calc: http://www.isthe.com/chongo/tech/comp/calc/

However, when I tried simple calculation like:

calc 3/(1+2)

It gave me this error message:

-bash: syntax error near unexpected token `('

However, this works fine:

calc 3*(1+2)

3*(1+2) = 9.000000

The server version is:

$ uname -sr
Linux 3.2.0-23-generic

Does anyone have any idea how the error came up? Thanks!

Was it helpful?

Solution

Okay. Here's what's going on.

This has nothing to do with calc, and everything to do with bash. To explain this, I'm first going to give an example with echo.

wlynch@host:/tmp/blah$ ls          # No files in this directory
wlynch@host:/tmp/blah$ echo *(3)   # This works as you expect.
*(3)                               #
wlynch@host:/tmp/blah$ echo *(4)   # This works as you expect.
*(4)                               #
wlynch@host:/tmp/blah$ touch 3     # Create a file named 3 in the directory.
wlynch@host:/tmp/blah$ ls          #
3                                  #
wlynch@host:/tmp/blah$ echo *(3)   # This now gives a different result!
3                                  #
wlynch@host:/tmp/blah$ echo '*(3)' # Quoting gives what you want.
*(3)                               #
wlynch@host:/tmp/blah$ echo *(4)   # This works as you previously expected.
*(4)

Note that the output has changed when we created a file in the directory named 3.

What's going on here is that *(pattern) is a wildcard. It's matching any count of the contained pattern. Bash also has a weird side effect, where if the pattern doesn't match, instead of returning nothing, it returns the pattern as seen originally.

So in your case, you're accidentally using one of bash's wildcard substitution methods. Pattern Matching.

Now, as to why /() fails? That's because parentheses are another command in bash, and this one just happens to be being used as a syntax error. Grouping Commands.

The solution, as mentioned in the other answers, it to surround your command line arguments with quotes, so that none of these features are enabled.


Also, just as an aside, we can disable the feature that *(pattern) uses. If we do this, then both /() and *() will fail because of the parentheses ():

wlynch@host:/tmp/blah$ shopt -s extglob
wlynch@host:/tmp/blah$ echo *()
*()
wlynch@host:/tmp/blah$ echo /()
bash: syntax error near unexpected token `('

wlynch@host:/tmp/blah$ shopt -u extglob
wlynch@host:/tmp/blah$ echo *()
bash: syntax error near unexpected token `('
wlynch@host:/tmp/blah$ echo /()
bash: syntax error near unexpected token `('

OTHER TIPS

You just need to add quotes to the arithmetic expression :

Ex :

$ calc '3/(1+2)'
    1

"USE MORE QUOTES!" They are vital. Also, learn the difference between ' and " and `. See http://mywiki.wooledge.org/Quotes and http://wiki.bash-hackers.org/syntax/words

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top