Por que você está chamando sh
, se é um script bash? É claro que no seu sistema, sh
não é bash, mas algum outro shell na família Bourne / POSIX. Na verdade, é dash , um shell menor projetado para baixo consumo de memória e velocidade que praticamente só suporta < a href="http://pubs.opengroup.org/onlinepubs/009695399/idx/xcu.html"> POSIX constrói e utilitários integrados.
[[ … ]]
é uma extensão ksh para a sintaxe Bourne que foi escolhida por bash e zsh mas não por POSIX. Em um script portátil, você precisa usar [ … ]
para testes. A construção padrão não tem nenhum suporte para correspondência de padrões; o idioma padrão é usar um case
construct :
case $1 in # branch to the first pattern that $1 matches
*[!0-9]*) # pattern = anything containing a non-digit
echo not a number # do this if the first pattern triggered
;; # end of this case branch
*) # pattern = anything (else)
echo successor of $(($1-1)) # do this if the second pattern triggered
;; # end of this case branch
esac # end of the case construct
Aqui está uma função que testa se o argumento é de todos os dígitos:
is_all_digits () {
case $1 in *[!0-9]*) false;; esac
}
Digression : Eu inicialmente cometi um erro de digitação no snippet acima: Escrevi $(($0-1))
. Isso causou mensagens de erro com aparência estranha:
$ ash foo.sh 42
foo.sh: 4: arithmetic expression: expecting EOF: "foo.sh-1"
$ ash ./foo.sh 42
./foo.sh: 4: arithmetic expression: expecting primary: "./foo.sh-1"
$ ksh ./foo.sh 42
./foo.sh: line 3: foo.sh: invalid variable name
$ pdksh ./foo.sh 42
./foo.sh[4]: ./foo.sh-1: unexpected '.'
$ bash foo.sh 42
foo.sh: line 3: foo.sh-1: syntax error: invalid arithmetic operator (error token is ".sh-1")
$ bash ./foo.sh 42
./foo.sh: line 3: ./foo.sh-1: syntax error: operand expected (error token is "./foo.sh-1")
$ zsh foo.sh 42
foo.sh:3: bad floating point constant
$0
é o nome do script, portanto, a expressão aritmética a ser avaliada é foo.sh-1
ou ./foo.sh-1
. Você pode observar a diversidade de mensagens de erro entre os shells. Fiquei um pouco surpreso ao ver que as mensagens das cinzas e a mensagem de bash sem ./
eram as mais claras: nenhuma das outras conchas menciona que o problema está em uma expressão aritmética. Ash e pdksh conseguem pontos atracados por reportar o erro em uma linha longe demais.