if, elif, else problemi di istruzione in Bash


359

Non riesco a capire quale sia il problema con la seguente ifdichiarazione per quanto riguarda il elife then. Tieni presente che printfè ancora in fase di sviluppo. Non sono stato ancora in grado di testarlo nella dichiarazione, quindi è più che probabilmente sbagliato.

L'errore che sto ricevendo è:

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

E l'affermazione è così.

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

7
Mi chiedo perché abbiamo bisogno della thendichiarazione ife elif, ma non in else, e anche in generale.

@ w17t, perché dobbiamo separare la condizione dalla sequenza.
Sasha,

3
@codeforester Non vedo molta logica nel contrassegnare una domanda di 500K viste come duplicata di una che ha solo 5K
fedorqui "COSÌ smetti di danneggiare"

L'uso di alcuni strumenti di formattazione automatica del codice potrebbe aiutarti aggiungendo / rimuovendo automaticamente gli spazi tra parentesi. Puoi cercare plugin per il tuo editor.
Nj Subedi,

Risposte:


453

Manca uno spazio tra elife [:

elif[ "$seconds" -gt 0 ]

dovrebbe essere

elif [ "$seconds" -gt 0 ]

Dal momento che vedo che questa domanda sta ottenendo molte visualizzazioni, è importante indicare che la sintassi da seguire è:

if [ conditions ]
# ^ ^          ^

nel senso che sono necessari spazi attorno alle parentesi . Altrimenti, non funzionerà. Questo perché di per [è un comando.

Il motivo per cui non si è visto qualcosa di simile elif[: command not found(o simile), è che dopo aver visto ife then, il guscio è alla ricerca di uno elif, elseo fi. Tuttavia ne trova un altro then(dopo la formattazione errata elif[). Solo dopo aver analizzato l'istruzione verrà eseguita (e elif[: command not foundverrà emesso un messaggio di errore come ).


33
Il motivo per cui le parentesi hanno bisogno di spazi è perché sono solo scorciatoie per programmi reali (almeno la prima parentesi, la seconda è solo zucchero sintattico per come la comprendo). Per dare un senso, vedi la manpage effettiva per la parentesi sinistra:$ man [
Michael Johansen,

3
Questo post non dovrebbe essere chiuso come errore di battitura?
zx8754,

3
@ zx8754 avrebbe potuto essere, ma non è diventato un modo canonico per correggere questo errore, che sembra abbastanza utile (visualizzazioni a 360K e conteggio).
fedorqui "SO smettere di danneggiare" il

3
Alcuni dei miei colleghi non capiscono il concetto di "spazio" o "stile di codifica", quindi potrebbe non essere un errore di battitura.
juzzlin,

3
[è una specie di alias per il comando test. Questo è il motivo per cui è richiesto il carattere vuoto. if test "$seconds" -eq 0; then ... fiè equivalente a if [ "$seconds" -eq 0 ];then ... fi ]. @LeiYang man testè quello che stai effettivamente cercando
Melicerte,

304

Hai alcuni problemi di sintassi con il tuo script. Ecco una versione fissa:

#!/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

76
Stranamente, questo era l'unico costrutto "if-then-else" completo e semplice che bash ho trovato facilmente su stackexchange ... grazie.
Wildcard il

1
il rientro è facoltativo. l'interprete può (e dovrebbe) essere #!/bin/sh.

3
@ Chinggis6 Assurdità totale, l'interprete potrebbe essere #!/bin/shma non è necessario.
Camusensei,

4
@Camusensei non è un'assurdità totale come shpuò essere usata invece per una maggiore compatibilità (non tutte le distribuzioni * nix hanno bash come shell predefinita (alcune hanno ksh o ash ma la maggior parte di esse dipende dallo standard shper funzionare). Inoltre, se bash è specifico o le funzioni avanzate non vengono utilizzate nello script, quindi "sh" dovrebbe essere usato come interprete (un motivo in più per esso) in quanto può gestire lo script da solo.

6
@ Chinggis6 Vero, pessima scelta di parole dalla mia parte.
Camusensei,

25

[è un comando (o un builtin in alcune shell). Deve essere separato da uno spazio bianco dall'istruzione precedente:

elif [

3
È sostituito da un built-in in bash, ma il tuo messaggio è ancora corretto. usarlo type -a [per vederlo.
Camusensei,

È anche un binario che mi è sempre sembrato strano.
mr.zog,

4

Ti consiglierei di dare un'occhiata alle basi del condizionamento in bash.

Il simbolo "[" è un comando e deve avere uno spazio prima di esso. Se non dai spazio bianco dopo il tuo elif, il sistema interpreta elif [ come un comando particolare che sicuramente non è quello che vorresti in questo momento.

Uso:

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

In breve, modifica il tuo segmento di codice in:

elif [ "$seconds" -gt 0 ]

Staresti bene senza errori di compilazione. Il segmento di codice finale dovrebbe essere simile al seguente:

#!/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

2

Lo spazio mancante tra elife il [resto del programma è corretto. è necessario correggerlo e verificarlo. ecco un programma fisso:

#!/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 utile relativo a questa istruzione bash if else

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.