347 votes

Exécution de plusieurs commandes Linux combinées sur une seule ligne

J'essaie de fusionner plusieurs commandes linux en une seule ligne pour effectuer une opération de déploiement. Par exemple

cd /my_folder
rm *.jar
svn co path to repo
mvn compile package install

753voto

Nikos C. Points 18676

Si vous voulez exécuter chaque commande uniquement si la précédente a réussi, combinez-les en utilisant la commande && opérateur :

cd /my_folder && rm *.jar && svn co path to repo && mvn compile package install

Si l'une des commandes échoue, toutes les autres commandes qui la suivent ne seront pas exécutées.

Si vous voulez exécuter toutes les commandes, que les précédentes aient échoué ou non, séparez-les par des points-virgules :

cd /my_folder; rm *.jar; svn co path to repo; mvn compile package install

Dans votre cas, je pense que vous voulez le premier cas où l'exécution de la commande suivante dépend du succès de la précédente.

Vous pouvez également placer toutes les commandes dans un script et l'exécuter à la place :

#! /bin/sh

cd /my_folder \
&& rm *.jar \
&& svn co path to repo \
&& mvn compile package install

Les barres obliques inversées à la fin de la ligne sont là pour empêcher le shell de penser que la ligne suivante est une nouvelle commande ; si vous omettez les barres obliques inversées, vous devrez écrire la commande entière sur une seule ligne.

Un moyen plus pratique que d'utiliser les barres obliques inversées et les touches && partout est d'instruire le shell de quitter le script si l'une des commandes échoue. Vous faites cela en utilisant l'option set avec la fonction intégrée -e argument. Avec cela, vous pouvez écrire un script d'une manière beaucoup plus naturelle :

#! /bin/sh
set -e

cd /my_folder
rm *.jar
svn co path to repo
mvn compile package install

Sauvegardez-le dans un fichier, par exemple myscript et le rendre exécutable :

chmod +x myscript

Vous pouvez maintenant exécuter ce script comme les autres programmes de la machine. Mais si vous ne le placez pas à l'intérieur d'un répertoire listé dans votre fichier PATH variable d'environnement (par exemple /usr/local/bin ou sur certaines distributions Linux ~/bin ), alors vous devrez spécifier le chemin vers ce script. S'il se trouve dans le répertoire courant, vous l'exécutez avec :

./myscript

Les commandes du script fonctionnent de la même manière que les commandes du premier exemple ; la commande suivante ne s'exécute que si la précédente a réussi. Pour une exécution inconditionnelle de toutes les commandes, il suffit de ne pas appeler set -e :

#! /bin/sh

cd /my_folder
rm *.jar
svn co path to repo
mvn compile package install

44 votes

Pour les futurs lecteurs : Vous pouvez également utiliser || au lieu du point-virgule ou && si vous voulez que la commande suivante soit exécutée uniquement si la dernière a échoué. Par exemple, essayez ceci, et si cela échoue, essayez cela.

3 votes

Hm, le point-virgule ne fonctionne pas toujours. Par exemple. ls >/dev/null & ; echo $! déclenche une erreur.

2 votes

Et si je veux exécuter la première commande en arrière-plan et une autre en avant-plan ? J'essaie ceci tail -f my.log & && ./myscript qui ne fonctionne pas veuillez suggérer.

47voto

Dean Points 91

J'ai découvert que l'utilisation de ; pour séparer les commandes ne fonctionne qu'au premier plan. par exemple :

cmd1; cmd2; cmd3 & - n'exécutera que cmd3 en arrière-plan, tandis que cmd1 && cmd2 && cmd3 & - exécutera l'ensemble de la chaîne en arrière-plan SI aucune erreur n'est constatée.

Pour tenir compte de l'exécution inconditionnelle, l'utilisation de parenthèses permet de résoudre ce problème :

(cmd1; cmd2; cmd3) & - exécutera la chaîne de commandes en arrière-plan, même si une étape échoue.

2 votes

L'esperluette de fin (&) dans vos exemples était-elle intentionnelle ? Si oui, à quoi sert-elle ?

6 votes

@Technophile C'est pour faire fonctionner un commande de fond

1 votes

Une réponse simple, courte et directe, vous devriez utiliser plus souvent les sites StackExchange Dean. Merci pour votre contribution.

10voto

andrux Points 843

Vous pouvez séparer vos commandes en utilisant un point-virgule :

cd /my_folder;rm *.jar;svn co path to repo;mvn compile package install

C'est ce que tu voulais dire ?

2voto

Mark Stevens Points 1768
cd /my_folder && rm *.jar && svn co path to repo && mvn compile package install

0 votes

Ce n'est pas la même chose que le script de l'OP, s'il vous plaît expliquez : si une commande échoue, le script abandonne.

5 votes

En outre, vous pouvez utiliser cmd1 || cmd2 séparateur si vous avez besoin cmd2 à exécuter uniquement si cmd1 retourne un statut non nul au shell, et vous pouvez utiliser cmd1 ; cmd2 si vous voulez exécuter les deux commandes sans tenir compte de leur statut de retour.

0 votes

@sputnick Il devrait l'être, je l'ai juste collé et concaténé les commandes avec &&.

1voto

Prabhu Points 840

Si vous voulez exécuter toutes les commandes, que la précédente soit exécutée ou non, vous pouvez utiliser le point-virgule ( ;) pour séparer les commandes.

cd /my_folder; rm *.jar; svn co path to repo; mvn compile package install

Si vous voulez exécuter la commande suivante uniquement si la commande précédente réussit, vous pouvez utiliser && pour séparer les commandes.

cd /my_folder && rm *.jar && svn co path to repo && mvn compile package install

Dans votre cas, l'exécution de commandes consécutives semble dépendre des commandes précédentes, utilisez donc le deuxième exemple, c'est-à-dire utilisez && pour joindre les commandes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X