Je lisais le livre d’O'Reilly "Unix en un mot" et j’y ai vu que les commandes peuvent être regroupées et exécutées dans le shell actuel au format suivant:
{ cmd1 ; cmd2 }
Je ne comprenais pas comment cela était possible, car je savais qu'un appel à exec remplaçait les données d'un shell et que, par conséquent, ce dernier ne pouvait pas revenir d'un appel système exec. J'ai donc testé la commande et je ne comprends pas ce qui s'est passé. Je suis entré dans une ligne de commande et je ne suis pas sûr de savoir à quoi appartient la ligne de commande.
S'agit-il uniquement de la ligne de commande de l'émulateur de terminal, séparée du shell?
En outre, en quoi l’exécution de commandes dans le shell actuel est-elle utile?
un appel à exec remplace les données d'un shell, qui ne peut donc pas être renvoyé à partir d'un appel système exec.
Mais toutes les commandes ne sont pas le nom d'un programme à exécuter. Très souvent, il n'y a pas d'appel exec
impliqué. La différence essentielle est que contrairement à ( cmd1; cmd2; )
, vous ne recevez pas un autre processus Shell. Ou peut-être plus correctement, le Shell ne fera que bifurquer pour exécuter des programmes enfants, pas pour exécuter des processus Shell.
à quoi appartient la ligne de commande.
Comme d'autres réponses l'ont souligné, votre commande était incomplète. La ligne de commande appartenait donc à bash elle-même, qui attendait la fin de votre groupe.
En outre, en quoi l’exécution de commandes dans le shell actuel est-elle utile?
L'exemple le plus frappant concerne la définition de variables dans cette sous-commande. Ton ça:
foo=1; { foo=2; echo $foo; }; ( foo=3; echo $foo; ); echo $foo
Cela va imprimer
2
3
2
Ainsi, bien que vous ayez défini foo=3
dans un groupe, ce groupe a été exécuté dans un sous-shell et ses paramètres ne se sont pas propagés au parent.
Une autre chose à considérer est le répertoire de travail actuel. { cd foo; make; }
vous laissera dans le répertoire foo
alors que ( cd foo; make; )
ne modifiera pas le répertoire de travail actuel de votre shell principal.
Le regroupement est surtout utile si vous avez d’autres codes en dehors, par exemple. conditionnels
test -f foo && { echo "Foo exists."; rm foo; }
ou redirections
{ echo "Content of $PWD:"; ls; } | gzip > dirlist.gz
C'est parce que vous ne terminez pas la deuxième ligne: { cmd1; cmd2; }
est correct. Le point-virgule signifie "fin de commande".
La fonction intégrée help
peut être utile même pour le mot clé {
. De help -m {
:
NAME { ... } - Group commands as a unit. SYNOPSIS { COMMANDS ; }
Le point-virgule (;
) est donc obligatoire après chaque commande.