instrução if, elif, else emite no Bash

358

Não consigo entender qual é o problema da ifdeclaração a seguir em relação ao elife then. Lembre- printfse de que ainda está em desenvolvimento. Eu ainda não pude testá-lo na declaração, portanto é mais do que provável que esteja errado.

O erro que estou recebendo é:

./timezone_string.sh: line 14: syntax error near unexpected token `then'
./timezone_string.sh: line 14: `then'

E a afirmação é assim.

if [ "$seconds" -eq 0 ];then
   $timezone_string="Z"
elif[ "$seconds" -gt 0 ]
then
   $timezone_string=`printf "%02d:%02d" $seconds/3600 ($seconds/60)%60`
else
   echo "Unknown parameter"
fi
StuStirling
fonte
7
Eu me pergunto por que precisamos da thendeclaração em ife elifnão em else, e também em geral.
@ w17t, porque precisamos separar a condição da sequência.
Sasha
3
@codeforester Eu não vejo muita lógica em marcar uma pergunta de 500 mil visualizações como duplicada para uma que tem apenas 5
mil
O uso de algumas ferramentas de formatação automática de código pode ajudá-lo adicionando / removendo automaticamente espaços ao redor dos colchetes. Você pode procurar por plugins para o seu editor.
Nj Subedi

Respostas:

453

Falta um espaço entre elife [:

elif[ "$seconds" -gt 0 ]

deveria estar

elif [ "$seconds" -gt 0 ]

Como vejo que esta pergunta está obtendo muitas visualizações, é importante indicar que a sintaxe a seguir é:

if [ conditions ]
# ^ ^          ^

o que significa que são necessários espaços entre os colchetes . Caso contrário, não funcionará. Isso ocorre porque em [si é um comando.

A razão pela qual você não está vendo algo como elif[: command not found(ou similar) é que depois de ver ife then, a casca está à procura de um ou outro elif, elseou fi. No entanto, encontra outro then(após o formato incorreto elif[). Somente depois de analisar a instrução, ela seria executada (e uma mensagem de erro como elif[: command not foundseria exibida).

fedorqui 'Então pare de prejudicar'
fonte
33
A razão pela qual os colchetes precisam de espaços é porque são apenas atalhos para programas reais (pelo menos o primeiro colchete, o segundo é apenas açúcar sintático, como eu o entendo). Para entender isso, consulte a página de manual real do colchete esquerdo:$ man [
Michael Johansen
3
Esta postagem não deve ser fechada como erro de digitação?
Zx8754
3
O @ zx8754 poderia ter sido, mas não se tornou uma maneira canônica de corrigir esse erro, que parece bastante útil (visualizações e contagens em 360K).
fedorqui 'ASSIM, pare de prejudicar'
3
Alguns de meus colegas não entendem o conceito de "espaço" ou "estilo de codificação"; portanto, isso pode não ser um erro de digitação.
juzzlin
3
[é um tipo de alias para o comando test. É por isso que o caractere em branco é necessário. if test "$seconds" -eq 0; then ... fié equivalente a if [ "$seconds" -eq 0 ];then ... fi ]. @LeiYang man testé o que você realmente procurando
Melicerte
303

Você tem alguns problemas de sintaxe com seu script. Aqui está uma versão fixa:

#!/bin/bash

if [ "$seconds" -eq 0 ]; then
   timezone_string="Z"
elif [ "$seconds" -gt 0 ]; then
   timezone_string=$(printf "%02d:%02d" $((seconds/3600)) $(((seconds / 60) % 60)))
else
   echo "Unknown parameter"
fi
anubhava
fonte
76
Curiosamente, essa foi a única construção completa e simples bash "se-então-mais" que encontrei facilmente na stackexchange ... obrigado.
Curinga
11
recuo é opcional. o intérprete pode (e deve) ser #!/bin/sh.
3
@ Chinggis6 Total absurdo, o intérprete pode ser, #!/bin/shmas não precisa.
Camusensei 13/09/17
4
O @Camusensei não é um absurdo total, pois shpode ser usado para uma compatibilidade mais alta (nem todas as distros * nix têm o bash como shell padrão (alguns têm ksh ou ash, mas a maioria deles depende do padrão shpara funcionar). ou recursos avançados não está sendo usado no script, em seguida, 'sh' deve ser usado como o intérprete (mais uma razão para isso), pois ele pode lidar com o script por si só.
6
@ Chinggis6 Verdadeira, má escolha de palavras do meu lado.
Camusensei 14/09
25

[é um comando (ou embutido em algumas conchas). Ele deve ser separado por espaço em branco da instrução anterior:

elif [
choroba
fonte
3
Ele é substituído por um built-in no bash, mas sua mensagem ainda está correta. use type -a [para ver isso.
Camusensei 13/09/17
Também é um binário que sempre me pareceu estranho.
mr.zog
4

Eu recomendaria que você desse uma olhada nos conceitos básicos de condicionamento no bash.

O símbolo "[" é um comando e deve ter um espaço em branco antes dele. Se você não fornecer um espaço em branco após o elif, o sistema interpretará o elif [ como um comando específico que definitivamente não é o que você deseja no momento.

Uso:

elif(A COMPULSORY WHITESPACE WITHOUT PARENTHESIS)[(A WHITE SPACE WITHOUT PARENTHESIS)conditions(A WHITESPACE WITHOUT PARENTHESIS)]

Em resumo, edite seu segmento de código para:

elif [ "$seconds" -gt 0 ]

Você ficaria bem sem erros de compilação. Seu segmento de código final deve ficar assim:

#!/bin/sh    
if [ "$seconds" -eq 0 ];then
       $timezone_string="Z"
    elif [ "$seconds" -gt 0 ]
    then
       $timezone_string=`printf "%02d:%02d" $seconds/3600 ($seconds/60)%60`
    else
       echo "Unknown parameter"
    fi
Mr. Weirdo
fonte
2

Faltar espaço entre elife [descansar seu programa está correto. você precisa corrigi-lo e dar uma olhada. aqui é programa fixo:

#!/bin/bash

if [ "$seconds" -eq 0 ]; then
   timezone_string="Z"
elif [ "$seconds" -gt 0 ]; then
   timezone_string=$(printf "%02d:%02d" $((seconds/3600)) $(((seconds / 60) % 60)))
else
   echo "Unknown parameter"
fi

link útil relacionado a esta declaração bash if else

John Walsh
fonte