Comment exécuter plusieurs commandes d'arrière-plan dans bash sur une seule ligne?

169

J'exécute normalement plusieurs commandes avec quelque chose comme ceci:

sleep 2 && sleep 3

ou

sleep 2 ; sleep 3

mais que faire si je veux les exécuter tous les deux en arrière-plan à partir d'une commande de ligne de commande?

sleep 2 & && sleep 3 &

ne fonctionne pas. Et remplacer &∥

Y a-t-il un moyen de le faire?

Palais Chan
la source
8
Utilisez ()pour entourer la commande.
nhahtdh
1
unix.stackexchange.com/questions/67006/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Réponses:

319

Comment voulez-vous qu'ils fonctionnent exactement? Si vous voulez qu'ils soient démarrés en arrière-plan et exécutés séquentiellement , vous feriez quelque chose comme ceci:

(sleep 2; sleep 3) &

Si, par contre, vous souhaitez qu'ils s'exécutent en parallèle en arrière-plan, vous pouvez à la place faire ceci:

sleep 2 & sleep 3 &

Et les deux techniques pourraient être combinées, telles que:

(sleep 2; echo first finished) & (sleep 3; echo second finished) &

Bash étant bash, il existe souvent une multitude de techniques différentes pour accomplir la même tâche, bien que parfois avec des différences subtiles entre elles.

Kitsune
la source
20
C'est une réponse concise et bien pensée qui "apprend à un homme à pêcher" pour la vie. Merci.
ambrus
2
Que se passe-t-il si nous le faisons sleep 2 && sleep 3 &? Je l'ai essayé en bash et il semble fonctionner de la même manière (essayé avec écho).
Wajahat le
@HakanBaba, Oui, cela crée en effet un sous-shell en arrière-plan.
Douwe van der Leest
3
@Wajahat, avez-vous essayé sleep 2 && echo "foo" && sleep 3 & echo "bar""? L' &&opérateur dit au shell d'exécuter la commande avant lui, et seulement si cette commande s'exécute sans aucune erreur, le shell exécute la commande suivante. Ceci est essentiellement différent de ;, car ;permet à la commande suivante de s'exécuter quel que soit l'état de sortie de la commande précédente, sauf s'il s'agit d'une erreur fatale. Le &dit au shell d'exécuter toutes les commandes "connectées" qui le précèdent, en arrière-plan. «connecté» signifie ici que la commande fait partie d'un tube ( |) ou d'un opérateur logique.
Douwe van der Leest
Of these list operators, ‘&&’ and ‘||’ have equal precedence, followed by ‘;’ and ‘&’, which have equal precedence.dans le manuel de bash.
jinbeom hong le
49

Vous devez ajouter des parens dans votre dernière version -

(sleep 2 &) && (sleep 3 &)

ou cela fonctionne aussi -

(sleep 2 &) ; (sleep 3 &)
iagreen
la source
Remarque: Lorsqu'une liste est utilisée avec &, son état de sortie est toujours zéro. Ainsi, les deux cas ci-dessus font la même chose (le shell exécute les deux côtés tour à tour de manière asynchrone ).
jinbeom hong le
9

pour exécuter plusieurs commandes d'arrière-plan, vous devez ajouter la &fin de chaque commande. ex: (command1 &) && (command2 &) && (command3 &)

saeed
la source
5

Les réponses ci-dessus utilisent des parenthèses. Bash peut également utiliser des accolades dans un but similaire:

{ sleep 2 && sleep 3; } &

Notez que les accolades sont plus pointilleuses sur la syntaxe - l'espace après {, l'espace avant }et le point-virgule final sont requis. Dans certaines situations, les accolades sont plus efficaces car elles ne créent pas de nouveau sous-coque. Dans ce cas, je ne sais pas si cela fait une différence.

Greg Reagle
la source
1
Et quoi { sleep 2; sleep 3; } &?
Kenny Evitt
4

Cela marche:

$(sleep 2 &) && sleep 3 &

Vous pouvez également faire:

$(sleep 2 && sleep 3) &
Higuaro
la source
0

J'ai la même mission aussi. J'ai essayé (sleep2 ; fg )& sleep3 ; fg, ça marche. Et lorsque vous préassurez ctrl + c doublé, les deux processus peuvent être arrêtés.

dingyang wang
la source
0

Vous pouvez utiliser la substitution de commande bash $(command)comme ceci:

$(command1 ; command2) &

Notez que stdin et stdout sont toujours liés au processus parent et rediriger au moins le stdout peut être délicat. Ainsi, vous pouvez également enchaîner les commandes sur une seule ligne, puis passer la chaîne à la bashcommande pour générer un nouveau processus qui gérera l'exécution.

bash -c "command1 ; command2" & 

Ceci est particulièrement utile dans un script bash lorsque vous devez exécuter plusieurs commandes en arrière-plan.

Ces deux déclarations devraient être équivalentes. Un processus bash est généré dans les deux cas pour gérer la commande (chaîne de commandes) et &à la fin détache l'exécution.

Cette fois, vous pouvez ajouter &>/dev/nullavant le &à la fin de la commande pour rediriger au moins le stdout et éviter la sortie sur le stdout du processus parent. Quelque chose comme:

bash -c "command1 ; command2" &>/dev/null &
Bemipefe
la source
-1

Si vous souhaitez exécuter plusieurs commandes de manière séquentielle , il existe une méthode très simple qui fonctionne partout: créer un fichier! L'avantage de cette méthode est qu'elle est propre et simple.

Tout d'abord, créez votre fichier avec un nom, par exemple commands.sh. Ensuite, mettez vos commandes là-bas. Voici un exemple:

commands.sh:

#!/system/bin/sh

sleep 3;
sleep 2;

OK, maintenant nous sommes dans la dernière étape. Pour exécuter des commandes en arrière-plan (séquentiellement), exécutez simplement:

$ sh commands.sh &
MAChitgarha
la source