Les programmes «si» et «alors» sont-ils en fait

15

J'ai lu que le point-virgule est utilisé pour séparer les programmes:

$ echo 3; ls -la

Est-ce que cela signifie cela if, thenet elsey a- t-il des programmes distincts ici?

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

Cette question ne concerne pas les points-virgules.

Maxim Koretskyi
la source
2
Copie possible du point- virgule dans les structures conditionnelles
Stephen Rauch
1
@StephenRauch Pas vraiment un doublon. De plus, c'est une excroissance raisonnable de ce Q, comme une tentative de compréhension.
user207673
Formulation plus programmatique:[ $variable == abcdef ] && echo yes || echo no
Hagen von Eitzen
2
@HagenvonEitzen qui n'est pas strictement équivalent, si l'instruction dans la première branche échoue, la seconde s'exécutera également.
Morgen
Duplication possible de Quels sont les opérateurs de contrôle et de redirection du shell?
G-Man dit `` Réintègre Monica '' le

Réponses:

26

Les ;déclarations séparées (en gros). Il est (presque) toujours possible de remplacer a ;par une nouvelle ligne.

Dire que ;sépare deux programmes, donc ifet thendoit être "programmes" est un peu trop simpliste car une déclaration peut être faite de mots réservés, de fonctions shell, d'utilitaires intégrés et d'utilitaires externes, et de combinaisons de ceux-ci en utilisant des tuyaux et des opérateurs booléens, etc. . etc.

Les deux ifet thensont des mots réservés dans la grammaire du shell , pas des "programmes". Ici, ils sont utilisés pour créer ce que l'on appelle techniquement une commande composée .

echoest probablement un utilitaire intégré dans le shell (mais ne doit pas l'être), et lsest probablement un utilitaire externe (ou "programme" comme vous le dites).

Kusalananda
la source
7

Bien que ce soit une première approximation juste quand on commence à apprendre les bases de l'utilisation des shells, au niveau de "voici comment on exécute un programme" et "voici comment on exécute plusieurs programmes les uns après les autres sur une seule ligne" , ce n'est pas vraiment vrai.

Le plus difficile à comprendre pour un débutant mais une explication plus correcte est que le langage shell est un langage informatique . Il a une syntaxe . Cette syntaxe comprend divers éléments lexicaux, y compris (entre autres) des sauts de ligne, des opérateurs, des mots et des mots réservés.

if, then, elseEt fisont tous des mots réservés . Ils ont des significations particulières lors de l' analyse de l'entrée que l'on donne à un shell, selon sa grammaire . De même, ;est un opérateur séparateur .

L'entrée en langage shell est donc, prise dans son ensemble, un programme informatique qui est interprété par un autre programme, un interprète , le shell. Ses parties grammaticales individuelles ne sont pas des programmes. Le langage shell est un moyen de spécifier (d'autres) programmes à exécuter par le shell.

[n'est pas un élément lexical spécial dans la grammaire du shell tel qu'un opérateur. C'est un mot ordinaire , qui nomme un tel programme nommé [. De nombreux shells ont une version intégrée de ce programme, combinée dans le code du programme shell lui-même, mais vous pouvez également trouver un programme externe de ce nom quelque part comme /bin/[ou /usr/bin/[, que d' autres programmes que les shells peuvent invoquer. De même, ce ]n'est pas non plus un élément lexical shell spécial. C'est un mot ordinaire, qui devient un argument pour le [programme. Le [programme requiert que son argument final, lors de son exécution, soit ], qu'il procède ensuite à ignorer.

Un autre programme similaire nommé dans votre question est echo. Encore une fois, la plupart des shells ont une version intégrée de ce programme. Mais encore une fois, il existe également une version externe du programme, quelque part comme /bin/echoou /usr/bin/echo, pour les programmes autres que les shells à invoquer.

Un troisième programme nommé dans votre question est ls. Les shells n'ont généralement pas de versions intégrées de ce programme, et il s'agit d'un programme externe, à trouver quelque part comme /bin/lsou /usr/bin/ls.

Pour le shell Bourne Again, vous pouvez en savoir plus à ce sujet dans la section Basic Shell Features of the GNU Bourne Again shell info documentation. D'autres coquilles ont naturellement des grammaires différentes. La spécification Unix unique décrit une syntaxe à laquelle tous les shells conformes POSIX (dans leurs modes conformes POSIX) sont censés adhérer.

Lectures complémentaires

  • " Shell Grammar ". Langage de commande Shell . Spécifications de base Problème 7. Le groupe ouvert. IEEE 1003.1-2008. ISBN 1937218812.
  • test. Utilitaires . Spécifications de base Problème 7. Le groupe ouvert. IEEE 1003.1-2008. ISBN 1937218812.
  • " Shell Grammar ". Le manuel Z Shell . version 5.3.1. 2017.
JdeBP
la source
5

Il est en fait pas exagéré de penser if, thenet elseque des programmes externes. En fait, le shell Thompson dans la 1ère édition originale Unix implémenté ifet en gototant que programmes externes. Cela est possible car le sous-processus partage les descripteurs de fichier avec le processus shell, donc un goto (avant) n'a eu qu'à lire l'entrée jusqu'à ce qu'il trouve l'étiquette cible puis se ferme. Voir coque Thompson .

Johan Myréen
la source
Ou bien de voir Laurent Bercot ifet ifelsequi font partie de execline. Ce ne sont pas les ifdans la question, cependant.
JdeBP
2
"Il n'est en fait pas farfelu de penser si, alors et autrement comme des programmes externes" Eh bien, c'est parce qu'ils ne le sont pas.
Courses de légèreté avec Monica le
2

Les thenet elsene sont pas des programmes. Les autres parties le sont. Remarquez qu'il n'y a pas ;directement après eux, mais après la commande, ils précèdent.

La [ ... ] est une commande et a besoin du ;si suivi du début d'une autre commande.

AFAIK, toutes les structures de contrôle dans Bash, et probablement la plupart des shells * nix, sont les mêmes. Ce sont des instructions à l'interprète. Le test ou la condition, d'autre part, utilise un programme / processus qui est "exécuté" et sont des commandes. Puisque thenfait partie de la ligne qui mène à la echocommande, elle doit être séparée par une nouvelle ligne de la commande précédente [ ... ]. Il n'a pas besoin d'être séparé de la commande qu'il contrôle, la echo yes.

Légalement, bien que laid et difficile à lire, vous pouvez également le faire.

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

Notez qu'il n'y a aucun besoin ;entre les contrôles ici, même s'ils ne sont pas sur leur propre ligne.

Chose intéressante, toute la structure de contrôle ( if ... fi) est une commande shell, et l'intégralité doit se terminer par une nouvelle ligne ou un ;. La dernière ligne ne peut pas être fi echo donemais doit l'être fi; echo done. La même chose qu'une affectation VARIABLE='abcdef'est une commande.

Même si l'ensemble des structures de contrôle sont des commandes, elles ne sont toujours pas des programmes.

user207673
la source
1

if, elif, then, Et fisont tous les mots clés réservés utilisés pour mettre en œuvre l' une des constructions appelé une commande composée en coquille, ce qui signifie qu'il ne peut y avoir une commande (ou plutôt, une autre commande) par l' un de ces noms en coquille. En ;général, le but n'est pas de séparer les commandes, mais de terminer une liste de commandes . Par exemple, ce qui suit est une ifdéclaration valide :

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

La condition de l' ifinstruction est la liste des commandes echo foo; echo bar; echo baz. L'analyseur sait que la condition est terminée car then, qui suit immédiatement un point-virgule, ne peut pas être une commande car il s'agit d'un mot clé réservé. Ainsi, il sait que ce qui suit then est le début du corps. De même, fiest un mot clé réservé et ne peut donc pas être une troisième commande dans le corps de l' ifinstruction, mais marque la fin de la commande composée.

chepner
la source
merci, si celui-ci est utilisé if program1 foo; program2 bar; program3 baz; , quel statut de programme devrait être 0, pour que le shell continue then? Le dernier?
Maxim Koretskyi
Justement program3 baz. L'état de sortie d'une liste de commandes est l'état de sortie de la dernière commande de cette liste. Les deux autres peuvent échouer sans affecter la condition.
chepner