J'ai rencontré un problème de mal de tête.
Je veux exécuter plusieurs commandes en arrière-plan, donc je veux les démarrer en bash un par un. Il est facile de lancer une commande dans un shell linux en arrière-plan, comme ceci:
myCommand &
Il est également facile de lancer plusieurs commandes, comme ceci:
myCommand1 && myCommand2
ou
myCommand1 ; myCommand2
Mais si je veux exécuter plusieurs commandes en arrière-plan, j'ai essayé le format de commande suivant, mais j'ai échoué:
myCommand1 & && myCommand2 &
ou
myCommand1 & ; myCommand2 &
Les deux formats échouent. Comment puis-je exécuter plusieurs commandes qui ont &
dans une ligne de commande?
Utilisation ().
Si vous voulez les exécuter séquentiellement:
(myCommand1; myCommand2) &
ou
(myCommand1 &) && (myCommand2 &)
Si vous voulez qu'ils soient parallèles:
myCommand1 & myCommand2 &
En bash, vous pouvez aussi utiliser ceci (les espaces derrière les {et les; sont obligatoires):
{ myCommand1 && myCommand2; } &
Je suppose que tu veux ça:
myCommand1 & myCommand2 &
Ceci démarre myCommand1
et l'envoie à l'arrière-plan, suivi de l'esperluette, puis démarre immédiatement myCommand2
et envoie également cette information à l'arrière-plan, libérant à nouveau le shell.
Pour une meilleure compréhension, vous pouvez remplacer pipeline par commande ici.
Une liste est une séquence d’un ou plusieurs pipelines séparés par l’un des opérateurs ; , & , && , ou || , et éventuellement terminé par l'un des ; , & , ou.
Si une commande est terminée par l'opérateur de contrôle & , le shell exécute la commande en arrière-plan dans un sous-shell. Le shell n'attend pas la fin de la commande et le statut de retour est 0. Les commandes séparées par un signe ; sont exécutées de manière séquentielle; le shell attend que chaque commande se termine à son tour. Le statut de retour est le statut de sortie de la dernière commande exécutée.
Les listes AND et OR sont des séquences d'un ou de plusieurs pipelines séparés par les caractères && et | | opérateurs de contrôle, respectivement.
Source:man bash
Divisons cela en exemples. Vous pouvez créer une liste en combinant des commandes et en les séparant avec l’un des éléments suivants: ; & && ||
:
command1 ; command2 # runs sequentially
command1 && command2 # runs sequentially, runs command2 only if command1 succeeds
command1 || command2 # runs sequentially, runs command2 only if command1 fails
command1 & command2 # runs simultaneously
Vous pouvez terminer les listes avec l’un de ces types: ; & <newline>
.
Normalement, vous exécutez une commande ou une liste en appuyant sur Enter, cela équivaut à <newline>
. Le point-virgule ;
a exactement le même objectif, notamment dans les scripts. Esperluette &
démarre toutefois la ou les commandes dans un sous-shell en arrière-plan, libérant immédiatement le shell.
Vous pouvez utiliser ()
ou des accolades {}
pour rapprocher les listes de groupes, à la différence que les accolades arrondies génèrent un sous-shell et que les bouclées ne le sont pas. Les accolades ont besoin d'un espace après le premier et d'un point-virgule ou d'une nouvelle ligne avant l'accolade fermante. Par exemple:
# if c1 succeeds start a Shell in the background
# and run c2 and c3 sequentially inside it
c1 && ( c2 ; c3 ) &
# run c1 and if it succeeds c2 sequentially as a group command
# if c1 or c2 fail run c3 in the background
{ c1 && c2 ;} || c3 &
Cela peut devenir assez compliqué, si vous n'êtes pas sûr, utilisez true
et false
pour vérifier si la construction fonctionne comme prévu:
$ { true && true ;} || echo 2
$ { true && false ;} || echo 2
2
La commande jobs
affiche une liste des travaux en arrière-plan en cours d'exécution ou récemment terminés dans le Shell en cours. Il existe un certain nombre de raccourcis clavier et de commandes permettant de contrôler le travail:
jobs
fg
= %
fait apparaître un processus au premier plan en le démarrant si nécessaire. Vous pouvez spécifier le processus comme suit:
% # last process in the jobs list
%1 # 1st process in the jobs list
%abc # process beginning with the string “abc”
%?abc # process containing the string “abc” anywhere
bg
= %&
prend un processus en arrière-plan en le démarrant si nécessaire:
%& # last process in the jobs list
%1& # 1st process in the jobs list
%abc& # process beginning with the string “abc”
%?abc& # process containing the string “abc” anywhere
wait
attend qu'un processus d'arrière-plan soit terminé et renvoie son statut de fin:
wait %1 # 1st process in the jobs list
Imaginez que vous ayez commencé un long processus (jobs
révèle que c'est le numéro 3) et réalisez ensuite que vous souhaitez que l'ordinateur soit suspendu à la fin de l'opération, plus echo
un message si le processus n'a pas abouti:
wait %3 || echo failed ; systemctl suspend