Parole chiave come if, then, else, fi, for, casee così via necessità di essere in un luogo in cui il guscio si aspetta un nome di comando. Altrimenti sono trattati come parole ordinarie. Per esempio,
echo if
stampa if, non avvia un'istruzione condizionale.
Quindi, in linea
if [ -r "$NAME" -af "$NAME" ] then
la parola thenè un argomento del comando [(di cui si lamenterebbe se dovesse mai essere eseguito). La shell continua a cercare il then, e trova una fiposizione di comando. Dal momento che c'è un oggetto ifche sta ancora cercando then, fiè inaspettato, c'è un errore di sintassi.
È necessario inserire prima un terminatore di comando in thenmodo che venga riconosciuto come parola chiave. Il terminatore di comando più comune è un'interruzione di riga, ma prima thenè comune utilizzare un punto e virgola (che ha esattamente lo stesso significato di un'interruzione di riga).
if [ -r "$NAME" -af "$NAME" ]; then
o
if [ -r "$NAME" -af "$NAME" ]
then
Una volta risolto il problema, otterrai un altro errore dal comando [perché non capisce -af. Presumibilmente intendevi
if [ -r "$NAME" -a -f "$NAME" ]; then
Sebbene i comandi di test appaiano come opzioni, non è possibile raggrupparli in questo modo. Sono operatori del [comando e devono essere ciascuno una parola separata (come do [e ]).
A proposito, anche se [ -r "$NAME" -a -f "$NAME" ]funziona, consiglio di scrivere neanche
[ -r "$NAME" ] && [ -f "$NAME" ]
o
[[ -r $NAME && -f $NAME ]]
È meglio mantenere [ … ] semplici i condizionali perché il [comando non è in grado di distinguere facilmente gli operatori dall'operando. Se $NAMEappare come un operatore e appare in una posizione in cui l'operatore è valido, potrebbe essere analizzato come operatore. Ciò non accadrà nei casi semplici visti in questa risposta, ma casi più complessi possono essere rischiosi. Scrivere questo con chiamate separate [e usare gli operatori logici della shell evita questo problema.
La seconda sintassi usa il [[ … ]]costrutto condizionale che esiste in bash (e ksh e zsh, ma non in sh). Questo costrutto è sintassi speciale, mentre [viene analizzato come qualsiasi altro comando, in tal modo è possibile utilizzare le cose come &&dentro e non è necessario per le variabili di citazione tranne in argomenti di alcuni operatori di stringa ( =, ==, !=, =~) (vedi Quando è doppi apici necessaria ? per i dettagli).