web-dev-qa-db-fra.com

Comment puis-je exécuter plusieurs commandes qui ont & dans une ligne de commande?

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?

10
Clock ZHONG

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; } &
19
Rinzwind

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.

Des listes

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

Contrôle du travail

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:

  • Ctrl+Z tape le caractère suspend qui arrête le processus en cours d'exécution au premier plan, il n'est pas terminé, mais reste dans la liste jobs
  • Ctrl+Y tape le caractère de suspension qui provoque l'arrêt du processus en cours d'exécution au premier plan lorsqu'il tente de lire une entrée du terminal
  • 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
    
15
dessert