Sono `if` e` then` in realtà programmi


15

Ho letto che il punto e virgola viene utilizzato per separare i programmi:

$ echo 3; ls -la

Vuol dire che if, thene elsequi sono programmi separati?

$ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi

Questa domanda non riguarda i punti e virgola.


2
Possibile duplicato di punto e virgola in strutture condizionali
Stephen Rauch,

1
@StephenRauch Non proprio un duplicato. Più è una ragionevole crescita da quella Q, come un tentativo di ulteriore comprensione.
user207673

Formulazione più programmata:[ $variable == abcdef ] && echo yes || echo no
Hagen von Eitzen,

2
@HagenvonEitzen non è strettamente equivalente, se l'istruzione all'interno del primo ramo fallisce, anche il secondo verrà eseguito.
Morgen,

Risposte:


26

Le ;dichiarazioni separate (parlando vagamente). È (quasi) sempre possibile sostituire a ;con una nuova riga.

Dire che ;separa due programmi, quindi ife thendeve essere "programmi" è un po 'troppo semplicistico in quanto un'affermazione può essere fatta di parole riservate, funzioni di shell, utilità integrate e utilità esterne e combinazioni di questi usando pipe e operatori booleani ecc. . eccetera.

Entrambi ife thensono parole riservate nella grammatica della shell , non "programmi". Qui vengono utilizzati per creare quello che tecnicamente viene chiamato comando composto .

echoè probabilmente un'utilità integrata nella shell (ma non è necessario che sia) ed lsè probabilmente un'utilità esterna (o "programma" come dici tu).


7

Mentre questa è una buona prima approssimazione quando si inizia a imparare le basi dell'uso delle shell, al livello di "ecco come si esegue un programma" e "ecco come si eseguono più programmi uno dopo l'altro su una sola riga" , in realtà non è vero.

Più difficile da capire per un principiante, ma una spiegazione più corretta è che il linguaggio shell è un linguaggio informatico . Ha una sintassi . Tale sintassi comprende vari elementi lessicali tra cui (tra le altre cose) newline, operatori, parole e parole riservate.

if, then, else, E fisono tutte parole riservate . Hanno significati particolari quando analizzano l'input che si dà a una shell, secondo la sua grammatica . Allo stesso modo, ;è un operatore separatore .

L'input nel linguaggio shell è quindi, nel suo insieme, un programma per computer interpretato da un altro programma, un interprete , la shell. Le sue singole parti grammaticali non sono programmi. Il linguaggio shell è un modo per specificare (altri) programmi per l'esecuzione della shell.

[non è un elemento lessicale speciale nella grammatica della shell come un operatore. È una parola ordinaria , che nomina uno di questi programmi chiamato [. Molte shell hanno una versione integrata di questo programma, combinata nel codice del programma shell stesso, ma puoi anche trovare un programma esterno con questo nome da qualche parte come /bin/[o /usr/bin/[, quali programmi diversi dalle shell possono invocare. Allo stesso modo, ]non è nemmeno uno speciale elemento lessicale della shell. È una parola normale, che diventa un argomento per il [programma. Il [programma richiede che il suo argomento finale, quando viene eseguito, sia ], che procede quindi a ignorare.

Un altro programma simile chiamato nella tua domanda è echo. Ancora una volta, la maggior parte delle shell ha una versione integrata di questo programma. Ma ancora una volta esiste anche una versione esterna del programma, da qualche parte come /bin/echoo /usr/bin/echo, per invocare programmi diversi dalle shell.

Un terzo programma chiamato nella tua domanda è ls. In genere le shell non hanno versioni integrate di questo programma, ed è un programma esterno, che si trova da qualche parte come /bin/lso /usr/bin/ls.

Per la shell Bourne Again, puoi leggere ulteriori informazioni al riguardo nelle Funzionalità di base della shell della documentazione delle informazioni sulla shell GNU Bourne Again. Altre shell hanno grammatiche diverse, naturalmente. Le specifiche Unix singole descrivono una sintassi che tutte le shell conformi a POSIX (nelle loro modalità conformi a POSIX) dovrebbero aderire.

Ulteriori letture

  • " Shell Grammar ". Shell Command Language . Specifiche di base Numero 7. Il gruppo aperto. IEEE 1003.1-2008. ISBN 1937218812.
  • test. Utilità . Specifiche di base Numero 7. Il gruppo aperto. IEEE 1003.1-2008. ISBN 1937218812.
  • " Shell Grammar ". Il manuale Z Shell . versione 5.3.1. 2017.

5

In realtà non è inverosimile pensare if, thene elsecome programmi esterni. In effetti, la shell Thompson nella prima edizione originale Unix implementata ife gotocome programmi esterni. Ciò è possibile perché il sottoprocesso condivide i descrittori di file con il processo di shell, quindi un goto (in avanti) ha dovuto solo leggere l'input fino a quando non trova l'etichetta di destinazione e quindi esce. Vedi la shell Thompson .


O in effetti vedi Laurent Bercot ife quelli di ifelsecui fanno parte execline. Questi non sono ifnella domanda, però.
JdeBP,

2
"In realtà non è inverosimile pensare se, allora e altro come programmi esterni" Beh, lo è, perché non lo sono.
Corse di leggerezza con Monica il

2

I thene elsenon sono programmi. Le altre parti sono. Notate che non c'è ;'direttamente dopo di loro, ma dopo il comando che precedono.

Il [ ... ] è un comando, e deve la ;se seguita per l'inizio di un altro comando.

AFAIK, tutte le strutture di controllo in Bash, e probabilmente la maggior parte delle shell * nix, sono uguali. Sono istruzioni per l'interprete. Il test o la condizione, d'altra parte, utilizza un programma / processo che viene "eseguito" e sono comandi. Poiché thenfa parte della riga che conduce al echocomando, deve essere separato da una nuova riga dal comando precedente [ ... ]. Non ha bisogno di essere separato dal comando che controlla, il echo yes.

Legalmente, anche se brutto e difficile da leggere, potresti anche farlo.

if [ $VARIABLE == abcdef ]
then echo yes
else echo no
fi

Si noti che non è necessario ;tra i controlli qui, anche se non sono sulla propria linea.

È interessante notare che l'intera struttura di controllo ( if ... fi) è un comando di shell e il tutto deve terminare con una nuova riga o a ;. L'ultima riga non può essere fi echo donema deve essere fi; echo done. Lo stesso di un compito VARIABLE='abcdef'è un comando.

Anche se tutte le strutture di controllo sono comandi, non sono ancora programmi.


1

if, elif, then, E fisono tutte le parole chiave riservate utilizzati per implementare uno dei costrutti indicati come un comando composto in guscio, che significa che non vi può essere un comando (o meglio, un altro comando) da qualsiasi di quei nomi in guscio. Lo scopo di ;in generale non è di separare i comandi, ma di terminare un elenco di comandi . Ad esempio, quanto segue è ifun'istruzione valida :

if echo foo; echo bar; echo baz; then echo done; echo really done; fi

La condizione ifdell'istruzione è l'elenco dei comandi echo foo; echo bar; echo baz. Il parser sa che la condizione è finita perché then, che segue immediatamente un punto e virgola, non può essere un comando perché è una parola chiave riservata. Quindi, sa che ciò che segue then è l'inizio del corpo. Allo stesso modo, fiè una parola chiave riservata e quindi non può essere un terzo comando nel corpo ifdell'istruzione, ma segna la fine del comando composto.


grazie, se utilizzato if program1 foo; program2 bar; program3 baz; , quale stato del programma dovrebbe essere 0, in modo che la shell proceda then? L'ultimo?
Maxim Koretskyi il

Basta program3 baz. Lo stato di uscita di un elenco di comandi è lo stato di uscita dell'ultimo comando in quell'elenco. Gli altri due possono fallire senza influire sulla condizione.
Chepner,
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.