Quels sont les opérateurs de contrôle et de redirection du shell?

248

Je vois souvent des tutoriels en ligne qui relient diverses commandes avec différents symboles. Par exemple:

command1 |  command2
command1 &  command2
command1 || command2    
command1 && command2

D'autres semblent relier des commandes à des fichiers:

command1  > file1
command1  >> file1

Quelles sont ces choses? Comment s'appellent-ils? Que font-ils? Est-ce qu'il y en a plus?


Méta fil à propos de cette question. .

terdon
la source

Réponses:

340

Ceux-ci s'appellent des opérateurs de shell et, oui, ils sont plus nombreux. Je vais donner un bref aperçu des plus courantes parmi les deux principales classes, les opérateurs de contrôle et les opérateurs de redirection , ainsi que leur fonctionnement par rapport au shell bash.

A. Opérateurs de contrôle

Dans le langage de commande shell, un jeton qui remplit une fonction de contrôle.
C'est l'un des symboles suivants:

&   &&   (   )   ;   ;;   <newline>   |   ||

Et |&en bash.

A !n'est pas un opérateur de contrôle mais un mot réservé . Il devient un NOT [opérateur de négation] logique à l'intérieur des expressions arithmétiques et des constructions de test (tout en nécessitant un délimiteur d'espace).

A.1 Liste des terminateurs

  • ; : Exécutera une commande après l'autre, quel que soit le résultat de la première.

    command1 ; command2

    Le premier command1est exécuté, au premier plan, et une fois terminé, command2il sera exécuté.

    Une nouvelle ligne qui ne se trouve pas dans un littéral de chaîne ou après certains mots clés n'est pas équivalente à l'opérateur point-virgule. Une liste de ;commandes simples délimitées reste une liste - comme dans l’analyseur du shell, il faut continuer à lire les commandes simples qui suivent une ;commande simple délimitée avant de s’exécuter, alors qu’une nouvelle ligne peut délimiter toute une liste de commandes - ou liste de listes. La différence est subtile, mais compliquée: puisque le shell n’a pas d’impératif préalable pour la lecture de données suivant une nouvelle ligne, la nouvelle ligne marque un point où le shell peut commencer à évaluer les commandes simples qu’il a déjà lues, alors qu’un point ;-virgule le fait. ne pas.

  • & : Ceci lancera une commande en arrière-plan, vous permettant de continuer à travailler dans le même shell.

     command1 & command2

    Ici, command1est lancé en arrière-plan et command2commence à s'exécuter immédiatement au premier plan, sans attendre command1de quitter.

    Une nouvelle ligne après command1est facultative.

A.2 Opérateurs logiques

  • && : Utilisé pour construire des listes AND, il vous permet d'exécuter une commande uniquement si une autre est sortie avec succès.

     command1 && command2

    Ici, command2sera exécuté après command1a terminé et seulement si command1a réussi (si son code de sortie était 0). Les deux commandes sont exécutées au premier plan.

    Cette commande peut aussi être écrite

    if command1
    then command2
    else false
    fi

    ou simplement if command1; then command2; fisi le statut de retour est ignoré.

  • || : Utilisé pour construire des listes OR, il vous permet d'exécuter une commande uniquement si une autre a été abandonnée sans succès.

     command1 || command2

    Ici, command2ne fonctionnera qu'en cas d' command1échec (s'il a renvoyé un état de sortie autre que 0). Les deux commandes sont exécutées au premier plan.

    Cette commande peut aussi être écrite

    if command1
    then true
    else command2
    fi

    ou d'une manière plus courte if ! command1; then command2; fi.

    Notez que &&et ||sont à gauche associative; voir Priorité des opérateurs logiques du shell &&, || pour plus d'informations.

  • !: Ceci est un mot réservé qui agit en tant qu'opérateur "not" (mais doit avoir un délimiteur), utilisé pour annuler le statut de retour d'une commande - renvoie 0 si la commande renvoie un statut différent de zéro, renvoie 1 si renvoie le statut 0 Aussi un NON logique pour l' testutilitaire.

    ! command1
    
    [ ! a = a ]

    Et un véritable opérateur NOT dans les expressions arithmétiques:

    $ echo $((!0)) $((!23))
    1 0

A.3 Opérateur de tuyauterie

  • |: L’opérateur de pipe, il passe la sortie d’une commande en entrée à une autre. Une commande créée par l'opérateur de canal s'appelle un pipeline .

     command1 | command2

    Toute sortie imprimée par command1est passée en entrée command2.

  • |&: Ceci est un raccourci pour 2>&1 |in bash et zsh. Il transmet à la fois la sortie standard et l'erreur standard d'une commande à une autre.

    command1 |& command2

A.4 Autre ponctuation de liste

;;est utilisé uniquement pour marquer la fin d'une déclaration de cas . Ksh, bash et zsh permettent également ;&de passer au cas suivant et ;;&(pas dans ATT ksh) de continuer et de tester les cas suivants.

(et )sont utilisés pour regrouper des commandes et les lancer dans un sous-shell. {et }aussi des commandes de groupe, mais ne les lancez pas dans un sous-shell. Voir cette réponse pour une discussion des différents types de parenthèses, crochets et accolades dans la syntaxe du shell.

B. Opérateurs de redirection

Opérateur de redirection

Dans le langage de commande du shell, jeton qui remplit une fonction de redirection. C'est l'un des symboles suivants:

<     >     >|     <<     >>     <&     >&     <<-     <>

Ceux-ci vous permettent de contrôler l'entrée et la sortie de vos commandes. Ils peuvent apparaître n'importe où dans une commande simple ou suivre une commande. Les redirections sont traitées dans l'ordre dans lequel elles apparaissent, de gauche à droite.

  • < : Donne une entrée à une commande.

    command < file.txt

    Ce qui précède s'exécutera commandsur le contenu de file.txt.

  • <>: idem que ci-dessus, mais le fichier est ouvert en mode lecture + écriture au lieu de lecture seule :

    command <> file.txt

    Si le fichier n'existe pas, il sera créé.

    Cet opérateur est rarement utilisé car les commandes ne lisent généralement que leur stdin, bien qu'il puisse s'avérer utile dans un certain nombre de situations spécifiques .

  • > : Dirige la sortie d'une commande dans un fichier.

    command > out.txt

    Ce qui précède sauvera la sortie de commandas out.txt. Si le fichier existe, son contenu sera écrasé et s'il n'existe pas, il sera créé.

    Cet opérateur est également souvent utilisé pour choisir si quelque chose doit être imprimé avec une erreur standard ou une sortie standard :

    command >out.txt 2>error.txt

    Dans l'exemple ci-dessus, >redirige la sortie standard et 2>redirige l'erreur standard. La sortie peut également être redirigée à l'aide de 1>mais, comme il s'agit de la valeur par défaut, le 1est généralement omis et écrit simplement comme >.

    Donc, pour courir commandsur file.txtet enregistrer sa sortie out.txtet les messages d'erreur dans error.txtvous courrais:

    command < file.txt > out.txt 2> error.txt
  • >|: Fait la même chose que >, mais écrasera la cible, même si le shell a été configuré pour refuser l'écrasement (avec set -Cou set -o noclobber).

    command >| out.txt

    S'il out.txtexiste, la sortie de commandremplacera son contenu. S'il n'existe pas, il sera créé.

  • >>: Fait la même chose que >, sauf que si le fichier cible existe, les nouvelles données sont ajoutées.

    command >> out.txt

    S'il out.txtexiste, la sortie de commandy sera ajoutée après tout ce qui s'y trouve déjà. S'il n'existe pas, il sera créé.

  • &>, >&, >>&Et &>>: (non standard). Redirige les erreurs standard et les sorties standard, en les remplaçant ou en les ajoutant, respectivement.

    command &> out.txt

    L'erreur standard et la sortie standard de commandseront enregistrées dans out.txt, en écrasant son contenu ou en le créant s'il n'existe pas.

    command &>> out.txt

    Comme ci-dessus, sauf que s'il out.txtexiste, la sortie et l'erreur de commandy seront ajoutées.

    La &>variante est originaire de bash, tandis que la >&variante provient de csh (des décennies plus tôt). Ils sont tous deux en conflit avec d'autres opérateurs shell POSIX et ne doivent pas être utilisés dans des shscripts portables .

  • <<: Un document ici. Il est souvent utilisé pour imprimer des chaînes multilignes.

     command << WORD
         Text
     WORD

    Ici, commandtout prendra jusqu'à ce qu'il trouve l' entrée suivante de WORD, Textdans l'exemple ci-dessus, en tant qu'entrée. Bien que cela WORDsoit souvent le cas EoF, il peut s'agir de n'importe quelle chaîne alphanumérique (et pas seulement) que vous aimez. Quand WORDest cité, le texte dans le présent document est traité littéralement et aucune expansion n'est effectuée (sur des variables par exemple). Si elle n'est pas citée, les variables seront développées. Pour plus de détails, voir le manuel bash .

    Si vous souhaitez diriger command << WORD ... WORDdirectement la sortie vers une ou plusieurs autres commandes, vous devez placer le canal sur la même ligne que << WORDvous ne pouvez pas le placer après le mot de fin ou sur la ligne suivante. Par exemple:

     command << WORD | command2 | command3...
         Text
     WORD
  • <<<: Voici des chaînes, similaires aux documents ici, mais destinées à une seule ligne. Celles-ci n'existent que dans le port Unix ou rc (d'où il provient), zsh, certaines implémentations de ksh, yash et bash.

    command <<< WORD

    Tout ce qui est donné WORDest étendu et sa valeur est passée en entrée command. Ceci est souvent utilisé pour passer le contenu des variables en entrée d'une commande. Par exemple:

     $ foo="bar"
     $ sed 's/a/A/' <<< "$foo"
     bAr
     # as a short-cut for the standard:
     $ printf '%s\n' "$foo" | sed 's/a/A/'
     bAr
     # or
     sed 's/a/A/' << EOF
     $foo
     EOF

Quelques autres opérateurs ( >&-, x>&y x<&y) peuvent être utilisés pour fermer ou dupliquer des descripteurs de fichier. Pour plus de détails, reportez-vous à la section correspondante du manuel de votre shell ( ici, par exemple, pour bash).

Cela ne concerne que les opérateurs les plus courants des obus Bourne-like. Certains shells ont quelques opérateurs de redirection supplémentaires.

Ksh, bash et zsh ont également des constructions <(…), >(…)et =(…)(celle-ci en zshseulement). Ce ne sont pas des redirections, mais des substitutions de processus .

terdon
la source
2
Il serait probablement utile de noter que tous les coquillages ne sont pas égaux, et en soulignant spécifiquement les caractéristiques spécifiques à Bash.
Greg Hewgill
1
@GregHewgill ouais, je me suis laissé aller en disant que je discutais en ce qui concerne bash. Ceci est considéré comme une question canonique pour clore les diverses questions "Que fait cette chose étrange?" Et la plupart d'entre elles proviennent d'utilisateurs de bash. J'espère que quelqu'un d'autre interviendra et répondra pour les obus autres que bash, mais mettre en évidence ceux spécifiques à bash a beaucoup de sens. Je devrai vérifier cependant, je ne sais pas quels sont ceux qui me viennent à l'esprit.
terdon
&>, >>>Et <<<sont non-POSIX est la référence à non seulement les caractères non-Alphanum dans le nom d'ici-doc. Cette réponse discute aussi très peu de choses sur la façon dont ils travaillent - par exemple, il est presque pire que inutile de parler d'une simple commande et une commande sans expliquer ce que ceux - ci et la façon dont le shell décide.
mikeserv
@ mikeserv merci. Ils travaillent sur bash et zsh cependant. Je ne sais pas ce qui est réellement spécifique à Bash dans cette liste. Je devrais passer par là et ajouter les coquillages dans lesquels chacun travaille, mais cela impliquerait de découvrir d'abord.
terdon
1
@ Arc676 Non, ils ne sont pas évalués comme étant vrais ou faux, c'est un contexte complètement différent. Cela signifie simplement qu'une valeur de sortie non-0 indique un problème (non false) et un code de sortie de 0 indique un succès (non true). Cela a toujours été le chemin et est assez standard. Un code de sortie non-0 indique une erreur dans tous les environnements que je connais.
terdon
62

Avertissement concernant '>'

Les débutants Unix qui viennent d’apprendre la redirection des E / S ( <et >) essaient souvent des choses comme:

commande ... fichier_entrée > the_same_file

ou

commande … < fichier      > the_same_file

ou, presque équivalent,

dossier de chat | commande …> the_same_file

( grep, sed, cut, sortEt spellsont des exemples de commandes que les gens sont tentés d'utiliser dans les constructions comme celles - ci.) Les utilisateurs sont surpris de découvrir que ces scénarios aboutissent dans le fichier se vider.

Une nuance qui ne semble pas être mentionnée dans l'autre réponse se cache dans la première phrase de la section Redirection de bash (1) :

Avant qu'une commande ne soit exécutée, son entrée et sa sortie peuvent être redirigées à l' aide d'une notation spéciale interprétée par le shell.

Les cinq premiers mots doivent être en gras, en italique, souligné, agrandi, clignotant, coloré en rouge et marqué d'une point d'exclamation en triangle rougeicône pour souligner le fait que le shell effectue la ou les redirection (s) demandée (s) avant l'exécution de la commande . Et rappelez-vous aussi

La redirection de la sortie entraîne l’ouverture du fichier… en écriture…. Si le fichier n'existe pas, il est créé. s'il existe, il est tronqué à une taille nulle.

  1. Donc, dans cet exemple:

    sort roster > roster

    le shell ouvre le rosterfichier en écriture en le tronquant (c.-à-d. en supprimant tout son contenu) avant que le sortprogramme ne commence à s'exécuter. Naturellement, rien ne peut être fait pour récupérer les données.

  2. On pourrait s'attendre naïvement à ce que

    tr "[:upper:]" "[:lower:]" < poem > poem

    pourrait être mieux. Comme le shell gère les redirections de gauche à droite, il s'ouvre poemen lecture (pour trl'entrée standard de), avant de l'écrire en écriture (pour la sortie standard). Mais ça n'aide pas. Même si cette séquence d'opérations génère deux descripteurs de fichier, ils renvoient tous deux au même fichier. Lorsque le shell ouvre le fichier en lecture, le contenu est toujours là, mais il continue à être compressé avant l'exécution du programme. 

Alors, que faire à ce sujet?

Les solutions comprennent:

  • Vérifiez si le programme que vous exécutez dispose de sa propre capacité interne permettant de spécifier l'emplacement de la sortie. Ceci est souvent indiqué par un -o(ou --output=) jeton. En particulier,

    sort roster -o roster

    est à peu près équivalent à

    sort roster > roster

    sauf que, dans le premier cas, le sortprogramme ouvre le fichier de sortie. Et il est assez intelligent pour ne pas ouvrir le fichier de sortie jusqu'à ce que après avoir lu tous les fichiers d'entrée (s).

    De même, au moins certaines versions de sedont une option -i(edit i n place) qui peut être utilisée pour écrire la sortie dans le fichier d’entrée (à nouveau, après que toutes les entrées aient été lues). Éditeurs comme ed/ ex, emacs, picoet vi/ vim permettent à l'utilisateur d'éditer un fichier texte et enregistrez le texte modifié dans le fichier d' origine. Notez que ed(au moins) peut être utilisé de manière non interactive.

    • via une caractéristique connexe. Si vous tapez , le contenu du tampon d'édition sera écrit , la sortie et insérée dans le tampon (en remplacement du contenu d'origine).:%!commandEntercommand
  • Simple mais efficace:

    commande ... fichier_entrée > TEMP_FILE   && mv TEMP_FILE  fichier_entrée

    Cela a pour inconvénient que, s’il input_files’agit d’un lien, il sera (probablement) remplacé par un fichier séparé. En outre, le nouveau fichier appartiendra à vous, avec les protections par défaut. Cela risque en particulier de rendre le fichier lisible par tout le monde, même si le fichier original input_filene l’était pas.

    Variations:

    • commandinput_file > temp_file && cp temp_file input_file && rm temp_file
      qui laissera (potentiellement) le temp_filemonde lisible. Encore mieux:
    • cp input_file temp_file && commandtemp_file > input_file && rm temp_file
      Celles-ci préservent l’état de la liaison, le propriétaire et le mode (protection) du fichier, éventuellement au prix de deux fois plus d’E / S. (Vous devrez peut - être utiliser une option comme -aou -psur cp pour lui dire de conserver les attributs.)
    • commandinput_file > temp_file &&
      cp --attributes-only --preserve=all input_file temp_file &&
      mv temp_file input_file
      (divisé en lignes séparées uniquement pour des raisons de lisibilité) Cela préserve le mode du fichier (et, si vous êtes root, le propriétaire), mais le fait appartenir à vous (si vous n'êtes pas root), et en fait un nouveau, fichier séparé.
  • Ce blog (édition de fichiers «sur place») suggère et explique

    {rm input_file   &&   command …> input_file ; } < fichier_entrée

    Cela nécessite de commandpouvoir traiter les entrées standard (mais presque tous les filtres le peuvent). Le blog lui-même appelle cela un kludge risqué et décourage son utilisation. Et cela créera également un nouveau fichier séparé (non lié à quoi que ce soit), appartenant à vous et avec les autorisations par défaut.

  • Le paquet moreutils a une commande appelée sponge:

    commandefichier_entrée | éponge le_same_file

    Voir cette réponse pour plus d'informations.

Voici quelque chose qui m'a complètement surprise: syntaxerror dit :

[La plupart de ces solutions] échouera sur un système de fichiers en lecture seule, où «lecture seule» signifie que vous $HOME serez en écriture, mais /tmpen lecture seule (par défaut). Par exemple, si vous avez Ubuntu et que vous avez démarré dans la console de récupération, c'est généralement le cas. En outre, l'opérateur here-document <<<n'y travaillera pas non plus, car il doit /tmpêtre lu / écrit car il y écrit également un fichier temporaire.
(cf. cette question inclut une stracesortie 'd)

Ce qui suit peut fonctionner dans ce cas:

  • Réservé aux utilisateurs expérimentés: si votre commande produit la même quantité de données en sortie qu’elle est saisie (par exemple sort, ou tr sans l’ option -dou -s), vous pouvez essayer:
    commandefichier_entrée | dd de = the_same_file conv = notrunc
    Reportez - vous à cette réponse et à cette réponse pour plus d'informations, y compris une explication de ce qui précède, et des solutions de rechange qui fonctionnent si votre commande produit la même quantité de données en sortie qu'il y a de données en entrée ou moins (par exemple grep, ou cut). Ces réponses ont l'avantage de ne pas nécessiter d'espace libre (ou très peu). Les réponses ci-dessus du formulaire exigent clairement qu'il y ait suffisamment d'espace libre pour que le système puisse contenir simultanément tout le fichier d'entrée (ancien) et le fichier de sortie (nouveau); Ceci est également vrai pour la plupart des autres solutions (par exemple, et ). Exception: nécessitera probablement beaucoup d'espace libre, carcommandinput_file > temp_file && …sed -ispongesort … | dd …sort a besoin de lire toutes ses entrées avant de pouvoir écrire une sortie, et il stocke probablement en mémoire tampon la plupart sinon la totalité de ces données dans un fichier temporaire.
  • Pour les utilisateurs avancés uniquement:
    commandefichier_entrée 1 <> the_same_file
    peut être équivalent à la ddréponse ci-dessus. La syntaxe ouvre le fichier nommé sur le descripteur de fichier pour les entrées et les sorties , sans le tronquer - une sorte de combinaison de et . Remarque: Certains programmes (par exemple, et ) peuvent refuser de s'exécuter dans ce scénario car ils peuvent détecter que l'entrée et la sortie sont le même fichier. Reportez - vous à cette réponse pour en savoir plus sur ce qui précède, ainsi qu’à un script qui permet à cette réponse de fonctionner s’il est garanti que votre commande produira la même quantité de données en sortie qu’il ya une entrée ou moins . Attention: je n'ai pas testé le script de Peter, je ne le garantis donc pas.n<> filen n<n>catgrep

Alors, quelle était la question?

Cela a été un sujet populaire sur U & L; il est abordé dans les questions suivantes:

… Et cela ne compte pas Super User ou Ask Ubuntu. J'ai incorporé beaucoup d'informations des réponses aux questions ci-dessus dans cette réponse, mais pas toutes. (Par exemple, pour plus d'informations, lisez les questions ci-dessus et leurs réponses.)

PS Je n'ai aucune affiliation avec le blog que j'ai cité ci-dessus.

Scott
la source
Comme cette question ne cesse de se poser, je me suis dit que je tenterais d'écrire une «réponse canonique». Devrais-je l'afficher ici (et peut-être y faire un lien avec certaines des questions les plus exposées à la traite), ou devrais-je passer à l'une des questions qui soulève réellement ce problème? Aussi, est-ce peut-être une situation où les questions devraient être fusionnées?
Scott
/ tmp Répertoire disponible pour les applications nécessitant un emplacement pour créer des fichiers temporaires. Les applications sont autorisées à créer des fichiers dans ce répertoire, mais ne supposent pas que ces fichiers sont préservés entre les invocations de l'application.
mikeserv
@ mikeserv: Oui, (1) je cite syntaxerror, et (2) j'ai dit que j'étais surpris. Je pensais que si quelque chose était en lecture-écriture, ce le serait /tmp.
Scott
Eh bien, la @syntaxerror chose dit est doublement étrange parce que, comme je pense, dashserait la coquille de récupération par défaut sur Ubuntu et non seulement pas comprendre un <<<herestring, mais il obtient également des tuyaux anonymes pour <<heredocuments et ne plaisante pas avec ${TMPDIR:-/tmp}pour cela but du tout. Voir ceci ou cela pour des démonstrations sur la gestion des documents ici. Aussi, pourquoi la même quantité de sortie ou moins d' avertissement?
mikeserv
@mikeserv: Eh bien, les dd … conv=notruncet les 1<>réponses ne tronquer le fichier de sortie, de sorte que , si la sortie de la commande est inférieure à l'entrée (par exemple grep), il y aura quelques octets de l'original reste à la fin du fichier. Et, si la sortie est plus grande que l'entrée (par exemple cat -n, nlou (potentiellement) grep -n), il y a un risque d'écraser les anciennes données avant de l' avoir lu.
Scott
29

Plus d' observations sur ;, &, (et)

  • Notez que certaines des commandes de la réponse de terdon peuvent être nulles. Par exemple, vous pouvez dire

    command1 ;

    (avec non command2). Ceci est équivalent à

    command1

    (c’est-à-dire qu’il passe tout simplement command1au premier plan et attend son achèvement. De manière comparable,

    command1 &

    (avec non command2) se lancera command1en arrière-plan, puis émettra immédiatement une autre invite du shell.

  • En revanche, command1 &&, command1 ||et command1 |ne font pas de sens. Si vous en tapez un, le shell supposera (probablement) que la commande est continuée sur une autre ligne. Il affichera l'invite du shell secondaire (continuation), qui est normalement défini sur >, et continue à lire. Dans un script shell, il va simplement lire la ligne suivante et l'ajouter à ce qu'il a déjà lu. (Attention: ce n'est peut-être pas ce que vous voulez.)

    Remarque: certaines versions de certains shells peuvent traiter des commandes incomplètes comme des erreurs. Dans de tels cas (ou dans les cas où vous avez une longue commande), vous pouvez mettre une barre oblique inverse ( \) à la fin d'une ligne pour indiquer au shell de continuer à lire la commande sur une autre ligne:

    command1  &&  \
    command2

    ou

    find starting-directory -mindepth 3 -maxdepth 5 -iname "*.some_extension" -type f \
                            -newer some_existing_file -user fred -readable -print
  • Comme dit terdon, (et )peut être utilisé pour regrouper des commandes. La déclaration selon laquelle ils ne sont «pas vraiment pertinents» dans cette discussion est discutable. Certaines des commandes dans la réponse de terdon peuvent être des groupes de commandes . Par exemple,

    ( command1 ; command2 )  &&  ( command3; command4 )

    est ce que ca:

    • Courez command1et attendez que ça finisse.
    • Ensuite, quel que soit le résultat de l'exécution de cette première commande, exécutez-le command2et attendez la fin.
    • Ensuite, si command2réussi,

      • Courez command3et attendez que ça finisse.
      • Ensuite, quel que soit le résultat de l'exécution de cette commande, exécutez-le command4et attendez la fin de l'opération.

      En cas d' command2échec, arrêtez de traiter la ligne de commande.

  • En dehors des parenthèses, |lie très étroitement, donc

    command1 | command2 || command3

    est équivalent à

    ( command1 | command2 )  ||  command3

    et &&et ||lier plus serré que ;, donc

    command1 && command2 ; command3

    est équivalent à

    ( command1 && command2 ) ;  command3

    c'est-à-dire, command3sera exécuté quel que soit le statut de sortie de command1et / ou command2.

G-Man
la source
Parfait, +1! J'ai dit qu'ils n'étaient pas pertinents parce que je ne voulais pas entrer dans autant de détails. Je voulais une réponse qui puisse servir de feuille de calcul rapide pour les débutants qui se demandent en quoi consistent tous les étranges gribouillis à la fin des différentes commandes. Je ne voulais pas dire qu'ils ne sont pas utiles. Merci d'avoir ajouté tout cela.
terdon
1
Je suis préoccupé par le problème de la "masse critique" - si nous publions tout ce que nous pourrions dire sur les obus, nous aurons notre propre version TL; DR du manuel de référence Bash.
G-Man
Il convient également de mentionner que, contrairement aux langues de la famille C, ;une erreur de syntaxe, et non une commande vide, est une erreur de syntaxe et non une instruction vide. C'est donc ; ;une erreur. (Un piège commun pour les nouveaux utilisateurs, IMHO). Aussi: ;;est un délimiteur spécial, pour les casedéclarations.
Muru
1
@muru: Bon point, mais généralisons-le. Tout des opérateurs de contrôle qui peuvent apparaître entre les commandes: ;, &&, ||, &et |, sont des erreurs si elles apparaissent avec rien qui les précède. En outre, terdon a répondu ;;(brièvement) dans sa réponse.
G-Man
1
@Wildcard: OK, je vois d'où tu viens. Le mot clé est "peut"; tout ce que je disais, c'est que je ne garantis pas que tous les réservoirs accepteront de telles constructions (c'est-à-dire, YMMV). Évidemment, j’ai écrit cela avant de connaître l’utilisation du linebreakjeton dans la grammaire du shell POSIX. Donc, il est peut-être prudent de dire que tous les shells compatibles POSIX les accepteront. Je maintiens ma déclaration comme un disclaimer général; Si vous trouvez un shell suffisamment ancien, tel qu'un shell Bourne ou plus ancien, tous les paris sont ouverts.
G-Man