6

When I run this script I get this error:

./myscript.sh: 16: arithmetic expression: expecting primary: "1 ** 1"

When I run this shell script with bash, as in #! /bin/bash on the first line, the math works properly; unfortunately I need to use /bin/sh. What am I doing wrong? I'm on Linux Mint if that matters.

#! /bin/sh

x=1
while [ $x -le 10 ]
do
    y=1
    while [ $y -le 10 ]
    do
        echo $(($y ** $x))"   \c"
        y=`expr $y \+ 1`
    done
    echo
    x=`expr $x \+ 1`
done
6

Standard shell arithmetic only allows integer arithmetic operations. This doesn't include ** for exponentiation, which bash has as an extension.

Integer exponentiation is easy enough to implement as a shell function (though you'll run into wraparound soon).

pow () {
    set $1 $2 1
    while [ $2 -gt 0 ]; do
      set $1 $(($2-1)) $(($1*$3))
    done
    echo $3
}

As an aside, why use expr here? Shell arithmetic can do addition.

  • Wow thank you so much. Another quick question if you don't mind... when writing a bash shell script, what is the bash version of \c... when I put that in it echo's it verbatum instead of the next echo being on the same line. – whuff739 Feb 23 '11 at 22:09
  • 1
    @whuff739: echo -n. If you want to be portable, use printf %s 'print\this!exactly+with%no$newline*at;the&end'. – Gilles Feb 23 '11 at 22:14
  • You should also check out the bc program if you want to stuff other than basic add/multiply/subtract/divide. Example: echo $(echo '2^3' | bc) (using ksh here) – Nitrodist Feb 23 '11 at 22:16
  • @Nitrodist, I'll definitely look into that, thanks a lot. – whuff739 Feb 23 '11 at 22:18
2

I think you're out of luck, as the ** exponent operator isn't standard for /bin/sh. You can use bc, though: echo "$y ^ $x" | bc.

1

The POSIX shell apparently does not have an exponentiation operator. You can roll your own:

pow() {
    local x y res i
    x=$1
    y=$2
    res=1
    i=1
    while [ $i -le $y ]; do
        res=$(( res * x ))
        i=$(( i + 1 ))
    done
    echo $res
}

x=1
while [ $x -le 10 ]; do
    y=1
    while [ $y -le 10 ]; do
        echo "$(pow $y $x)   \c"
        y=$(( y + 1 ))
    done
    echo
    x=$(( x + 1 ))
done

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.