4

I have a problem with a bash script. I have to use the operator * to multiplicate. Instead the script bugs me with expansion and using as operator the name of the script itself. I tried with single quotes but it doesn't work :( Here's the code

#!/bin/bash -x

# Bash script that calculates an arithmetic expression
# NO PRECEDENCE FOR OPERATORS
# Operators: + - * 

if [ "$#" -lt "3" ]
then 
    echo "Usage: ./calcola.scr <num> <op> <num> ..."
    exit 1
fi

result=0
op=+
j=0

for i in "$@"
do
    if [ "$j" -eq "0" ]
    then
        # first try
        #result=$(( $result $op $i )) 

        # second try
        let "result$op=$i"

        j=1
    else
        op=$i
        j=0
    fi
done

echo "Result is $result"

exit 0
gc5
  • 9,468
  • 24
  • 90
  • 151

3 Answers3

8

If you don't need "* expansion" (referred as "globbing" in general) at all for your script, just start it with "-f"; you can also change it during run time:

mat@owiowi:/tmp/test$ echo *
A B
mat@owiowi:/tmp/test$ set -f
mat@owiowi:/tmp/test$ echo *
*
mat@owiowi:/tmp/test$ set +f
mat@owiowi:/tmp/test$ echo *
A B
MatthieuP
  • 1,116
  • 5
  • 12
  • I tried to use it in the script but it doesn't work.. :( It is because the command 'set -f' have to be called before the running of the script. I can't avoid expansion because it is done when the script starts. – gc5 Dec 28 '08 at 15:08
6

If "op" is "*", it will be expanded by the shell before your script even sees it. You need to choose something else for your multiplication operator, like "x", or force your users to escape it by putting it in single quotes or preceeding it with a backslash.

If the terms of the exercise allow it, maybe you should try using "read" to get the expression from standard input instead of getting them from the command line.

Paul Tomblin
  • 179,021
  • 58
  • 319
  • 408
  • It could be a good idea, but I have to make users to use * instead of escaped forms.. :( Because a goal of this exercise is to use * – gc5 Dec 16 '08 at 21:42
2

It works, you're just not escaping the * correctly. Try using the backslash:

$ ./calcola.scr 2 \* 3
+ '[' 3 -lt 3 ']'
+ result=0
+ op=+
+ j=0
+ for i in '"$@"'
+ '[' 0 -eq 0 ']'
+ let result+=2
+ j=1
+ for i in '"$@"'
+ '[' 1 -eq 0 ']'
+ op='*'
+ j=0
+ for i in '"$@"'
+ '[' 0 -eq 0 ']'
+ let 'result*=3'
+ j=1
+ echo 'Result is 6'
Result is 6
+ exit 0
$

Although, as Paul Tomblin mentioned, it would probably be better to use x as the multiplication operator instead.

Community
  • 1
  • 1
Jason Day
  • 8,809
  • 1
  • 41
  • 46
  • Yes the code works with escaped * .. I dont know.. Maybe the problem is in the request of the exercise. Btw thanks. :) – gc5 Dec 16 '08 at 21:51