Simple Shell Script com edição aritmética… ** está me causando problemas

6

Quando executo este script, recebo este erro:

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

Quando executo este script de shell com o bash, como em #! /bin/bash na primeira linha, a matemática funciona corretamente; infelizmente eu preciso usar /bin/sh . O que estou fazendo de errado? Eu estou no Linux Mint se isso importa.

#! /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
    
por whuff739 23.02.2011 / 22:45

3 respostas

5

A aritmética de shell padrão permite somente operações aritméticas inteiras. Isso não inclui ** para exponenciação, que o bash tem como extensão.

A exponenciação de números inteiros é fácil o suficiente para implementar como uma função de shell (embora você se envolva em breve).

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

Como um aparte, por que usar expr aqui? Aritmética shell pode fazer adição.

    
por 23.02.2011 / 23:03
2

Acho que você está sem sorte, pois o operador exponente de ** não é padrão para / bin / sh . Você pode usar bc , porém: echo "$y ^ $x" | bc .

    
por 23.02.2011 / 23:07
1

O shell POSIX aparentemente não possui um operador de exponenciação. Você pode rolar o seu próprio:

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
    
por 23.02.2011 / 23:07