Quelle est la signification de & à la fin d'une commande?

12

J'ai une ligne de script de démarrage:

pyprogramm >> /dev/null  2>&1 &

Signification:

>> /dev/null - redirect stdout to null device
2>&1 - redirect stderr to stdout (that is redirected to null device)

mais que signifie le tout dernier &?

vico
la source

Réponses:

16

Qu'est-ce que le & terminator?

L' &opérateur de fin à la fin d'une commande est utilisé pour mettre les commandes en arrière-plan. Il s'agit en fait d'une syntaxe standard spécifiée par la norme POSIX :

Listes asynchrones

Si une commande est terminée par l'opérateur de contrôle ('&'), le shell doit exécuter la commande de manière asynchrone dans un sous-shell. Cela signifie que le shell n'attendra pas la fin de la commande avant d'exécuter la commande suivante.

Le format d'exécution d'une commande en arrière-plan est le suivant:

command1 & [command2 & ...]

Le but des commandes d'arrière-plan est d'exécuter une commande sans le shell principal dans le script ou le shell interactif en attente de commande, ce qui bloquerait l'exécution d'autres commandes et inciterait l'utilisateur à attendre. C'est pratique pour démarrer des commandes de longue durée mais vous devez continuer à travailler dans le shell actuel. Comme vous pouvez le deviner, cela est né de l'époque où il n'y avait pas d'émulateurs de terminaux à plusieurs onglets, mais les terminaux étaient de véritables matériels physiques connectés à un ordinateur lui-même.

De la définition, vous pouvez voir que &sert également de terminateur de commande pour les listes de commandes, tout comme le ;fait. Dans votre exemple spécifique, pyprogramm >> /dev/null 2>&1 &il n'y a qu'une seule commande dans la liste.

Séquentiel; listes vs asynchrones et listes

Plus généralement,

echo Hello ; echo World ;

et

echo Hello & echo World &

sont deux exemples de listes terminées par les opérateurs ;et &. Une différence est que la &liste terminée aura une entrée connectée /dev/nullsi le contrôle des travaux est désactivé:

Si le contrôle des travaux est désactivé (voir set, -m), l'entrée standard pour une liste asynchrone, avant toute redirection explicite, doit être considérée comme affectée à un fichier ayant les mêmes propriétés que / dev / null. Cela ne doit pas se produire si le contrôle des travaux est activé. Dans tous les cas, la redirection explicite de l'entrée standard doit remplacer cette activité.

Dans la liste séquentielle, cependant, chaque commande s'est toujours stdinconnectée au terminal s'il n'y a pas de redirections explicites.

Notez également que, à partir de la définition que nous avons mentionnée précédemment, &exécute les commandes en sous-shell. En revanche, la ;liste terminée est exécutée dans le shell actuel. Il existe également des différences de statut de sortie. Car &la norme dit:

L'état de sortie d'une liste asynchrone doit être nul.

Ceci est important lorsque vous souhaitez mettre plusieurs commandes en arrière-plan. Lorsque vous écrivez un script ou une commande, vous devrez choisir des commandes dont vous ne vous souciez pas si elles ont échoué ou non, ou vous devrez trouver un moyen de gérer l'état de sortie non nul (erreur). Dans votre exemple spécifique, l' pyprogramm >> /dev/null 2>&1 &exécution en arrière-plan devrait avoir un moyen d'indiquer si elle a échoué ou non, mais en jugeant que vous utilisez, 2>&1vous masquez la sortie d'erreur en redirigeant, et vous supposez probablement que le script ne devrait pas échouer.

En revanche, l' ;état de sortie est défini comme:

L'état de sortie d'une liste séquentielle doit être l'état de sortie de la dernière commande de la liste.

Encore une fois, cela a des implications sur la façon dont vous écrivez une liste séquentielle de commandes en ligne de commande et sur la façon dont vous souhaitez que les choses soient gérées si certaines des commandes de la liste échouent.


Notes annexes et lectures supplémentaires

  • Le fait que ce moyen de définition POSIX que tous Bourne comme des coquilles, sens bash, dashet kshdoit le soutenir.

  • &en redirection est différent de &comme terminateur de commande. Cela signifie dupliquer (copier) l'objet descripteur de fichier. Voir Que signifie & signifie exactement dans la redirection de sortie?

  • Il bashy a aussi un |&opérateur (notez qu'il n'y a pas d'espace entre le tuyau et l'esperluette). Du manuel bash :

    Si | & est utilisé, l'erreur standard de la commande, en plus de sa sortie standard, est connectée à l'entrée standard de command2 via le tuyau; c'est un raccourci pour 2> & 1 |. Cette redirection implicite de l'erreur standard vers la sortie standard est effectuée après toutes les redirections spécifiées par la commande.

Sergiy Kolodyazhnyy
la source
2
Ce que vous dites sur le &masquage de la sortie ne semble pas correct. Le paragraphe de la norme que vous citez parle d' entrée et non de sortie . La raison pour laquelle la distinction entre le contrôle des travaux est activé ou non est qu'un processus d'arrière-plan tentant de lire à partir du tty sera suspendu. À ce stade, vous devez utiliser le contrôle des travaux pour le mettre au premier plan afin de fournir l'entrée qu'il attend. Tout cela ne peut pas être fait sans contrôle des travaux et donc si le contrôle des travaux est désactivé, le stdin doit être redirigé depuis /dev/nullou équivalent.
kasperd
J'ai également repéré une erreur dans votre montage. À un endroit, vous avez écrit activé où vous auriez dû écrire désactivé.
kasperd
@kasperd Ouais, je venais juste de relire la page POSIX quand je l'ai aussi remarqué. Déjà réparé. Faites-moi savoir si quelque chose d'autre a besoin d'être modifié. Merci :)
Sergiy Kolodyazhnyy
3

Cela signifie exécuter la commande en arrière-plan. Le script appelant continue plutôt que de bloquer jusqu'à ce que la commande appelée se termine.

Robert Longson
la source
0

&cela renvoie le contrôle du script au système d'exploitation mais a envoyé la réponse à l'arrière-plan pas car nohupcela envoie directement l'exécution entière

Bryro
la source