para sintaxe de loop no script de shell [duplicado]

4

Eu corro abaixo do script:

for (( i=1; i <= 5; i++ ))    
do
    echo "Random number $i: $RANDOM"
done

Estou ficando abaixo do erro:

Syntax error: Bad for loop variable

porque esta sintaxe não está funcionando?

    
por Akshay Patel 10.05.2015 / 20:12

3 respostas

7

Como a resposta de heemayl aponta, sua construção é um bashismo. A maneira padrão de fazer o que você quer seria:

for i in 1 2 3 4 5
do
  echo "Random number $i: $RANDOM"
done

Ou mais facilmente expansível:

for i in $(seq 1 5)
do
  echo "Random number $i: $RANDOM"
done

(Veja man seq para mais detalhes).

    
por evilsoup 10.05.2015 / 20:36
6

Seu script original tem uma (( i=1; i <= 5; i++ )) de construção em for loop, que é uma base e, portanto, não está sendo entendida por dash .

No Ubuntu sh é um link simbólico para dash , então quando você está rodando

sh ./script.sh

você está basicamente rodando

dash ./script.sh

Como mencionei anteriormente, o dash não está entendendo o constructo de loop for semelhante ao C, está mostrando o erro.

Para executar o script usando bash , você pode:

  • Execute-o como um argumento para bash , por exemplo bash script.sh (você não precisa tornar o script executável)

  • Torne o script executável e a partir de uma execução bash shell (do diretório que contém o script):

    ./script.sh 
    
  • A maneira mais portátil é usar um shebang ( #!/bin/bash ou preferencialmente #!/usr/bin/env bash ) como a primeira linha do seu script. Dessa forma, você pode executar o script a partir de qualquer shell por ./script.sh , o script será interpretado como um script bash e, portanto, será executado de acordo.

por heemayl 10.05.2015 / 20:25
3

Pensei em contribuir um pouco para a discussão.

Já foi mencionado que a sintaxe usada em seu script é uma base e, portanto, não é portátil, mesmo que seja semelhante a C e seja bem compreendida por pessoas familiarizadas com java e C. De perguntar a minha própria pergunta em unix.stackexchange.com, também aprendi que a sintaxe como for i in $(seq 1 5) gera um conjunto de números primeiro e então itera, o que pode ser um desperdício se você tiver um conjunto muito grande.

Uma maneira melhor de simular o comportamento semelhante ao C, que é portátil, é usar while loop, com uma variável que pode ser incrementada. Por exemplo,

#!/bin/sh
number=0
while [ "$number" -lt 10 ]
do
        printf "\t%d" "$number"
        number='expr $number + 1 '
done

Isso funciona com bash, dash, zsh, ksh, mksh. . . ou basicamente qualquer shell relacionado ao shell bourne. Na verdade, eu tenho um livro do Unix System V de 1995, e eu testei o exemplo deles para o bourne shell e ele ainda funciona. O comportamento também é o de C-like para loop: você tem condição inicial, condição de teste dentro de while [ . . .] e condição de atualização no final.

csh e tcsh têm sintaxe mais próxima da linguagem C, mas não é portável para outros shells, e eles não são recomendados para serem usados no script.

Adição :

Em relação à portabilidade de $ RANDOM, de acordo com a esta página no wiki do ubuntu, a geração de números aleatórios em traços deve depender usando /dev/urandom

    
por Sergiy Kolodyazhnyy 10.05.2015 / 22:35

Tags