Exécuter combiner plusieurs commandes Linux sur une seule ligne


329

J'essaie de fusionner plusieurs commandes Linux sur 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

Réponses:


717

Si vous souhaitez exécuter chaque commande uniquement si la précédente a réussi, combinez-les à l'aide de l' &&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 souhaitez 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 mettre 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 inverses à 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 inverses, vous devrez écrire la commande entière sur une seule ligne.)

Enregistrez-le dans un fichier, par exemple myscript, et rendez-le exécutable:

chmod +x myscript

Vous pouvez maintenant exécuter ce script comme d'autres programmes sur la machine. Mais si vous ne le placez pas dans un répertoire répertorié dans votre PATHvariable d'environnement (par exemple /usr/local/bin, ou sur certaines distributions Linux ~/bin), vous devrez spécifier le chemin d'accès à 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 s'exécute uniquement si la précédente a réussi. Pour une exécution inconditionnelle de toutes les commandes, listez simplement chaque commande sur sa propre ligne:

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

38
Pour les futurs lecteurs: vous pouvez également utiliser à la ||place du point-virgule ou &&si vous ne souhaitez exécuter la commande suivante que si la dernière a échoué. Comme pour essayer ceci, et s'il échoue, essayez cela.
DeVadder

3
Hm, les points-virgules ne fonctionnent pas toujours. Par exemple, ls >/dev/null & ; echo $!déclenche une erreur.
Hi-Angel

1
Et si je veux exécuter la première commande en arrière-plan et une autre en premier plan .. J'essaie ce tail -f my.log & && ./myscriptqui ne fonctionne pas .. veuillez suggérer.
OverrockSTAR

4
@Pareshkumar Avec bash, vous pouvez faire: { tail -f my.log & } && ./myscriptCependant, notez que le &&est inutile ici, car le premier travail s'exécute en arrière-plan et donc le deuxième travail ne peut pas connaître le résultat, car les deux travaux démarreront en même temps. Donc, vous pourriez aussi bien écrire:{ tail -f my.log & }; ./myscript
Nikos C.

Que faire si j'ai besoin d' sudoautorisations pour exécuter l'une des commandes? Dois-je mettre le sudoau début de toutes les commandes ou simplement celui qui en a besoin? Comment puis-je transmettre le mot de passe à cette commande afin qu'il soit correctement exécuté?
Drubio

46

J'ai trouvé cela en utilisant; séparer les commandes ne fonctionne qu'au premier plan. par exemple :

cmd1; cmd2; cmd3 & - ne s'exécutera cmd3qu'en arrière-plan, tandis que cmd1 && cmd2 && cmd3 &- exécutera toute la chaîne en arrière-plan SI il n'y a pas d'erreur.

Pour répondre à une exécution inconditionnelle, l'utilisation de parenthèses résout ce problème:

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


1
L'esperluette arrière (&) dans vos exemples était-elle intentionnelle? Si oui, à quoi ça sert?
Technophile

5
@Technophile C'est pour exécuter une commande d'arrière
Oak Chantosa

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

10

Vous pouvez séparer vos commandes à l'aide d'un point-virgule:

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

C'est ça que tu veux dire?


3

Pour les exécuter tous en même temps, vous pouvez utiliser la touche de ligne de tuyau "|" ainsi:

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

1
Le pipeline est utilisé pour donner la sortie de votre commande à la commande suivante en entrée. Par exemple: X | La sortie de la commande Y -> X fonctionnera comme entrée pour la commande Y
Arpan Saini

2

Si vous souhaitez exécuter toutes les commandes, que la précédente s'exécute ou non, vous pouvez utiliser un point-virgule (;) pour séparer les commandes.

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

Si vous souhaitez 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.


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

ce n'est pas la même chose que le script OP, veuillez expliquer: si une commande échoue, le script s'interrompt
Gilles Quenot

4
En outre, vous pouvez utiliser le cmd1 || cmd2séparateur si vous avez besoin cmd2de l'exécuter uniquement s'il cmd1renvoie un état différent de zéro au shell, et vous pouvez l'utiliser cmd1 ; cmd2si vous souhaitez exécuter les deux commandes indépendamment de leur état de retour.
Victor Sorokin

@sputnick Ça devrait être, je viens de le coller et de concaténer les commandes avec &&
Mark Stevens

3
@MarkStevens C'est une meilleure implémentation mais elle n'obtiendra pas les mêmes résultats que si les commandes étaient exécutées séquentiellement, je pense que c'est ce que signifiait sputnick.
andrux

1

Quelle est l'utilité d'une seule esperluette? Ce matin, j'ai fait un lanceur dans le panel XFCE (en Manjaro + XFCE) pour lancer 2 gestionnaires de mots de passe simultanément:

sh -c "keepassx && password-gorilla"
or
sh -c "keepassx; password-gorilla"

Mais ça ne marche pas comme je veux. IE, la première application démarre mais la seconde ne démarre que lorsque la précédente est fermée

Cependant, j'ai trouvé que (avec une seule esperluette):

sh -c "keepassx & password-gorilla"

et ça marche comme je veux maintenant ...


1
Esperluette agit comme un terminateur de commande similaire à ;, sauf que cela place le virgule devant lui en arrière-plan, c'est-à-dire que le shell ne verra pas sa sortie.
Sergiy Kolodyazhnyy

-1

Vous pouvez utiliser comme code suivant;

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

Ça marche...


-1

Je trouve beaucoup de réponses à ce genre de question trompeuses

Modifié de ce post: https://www.webmasterworld.com/linux/3613813.htm

Le code suivant crée une fenêtre bash et fonctionne exactement comme une fenêtre bash. J'espère que cela t'aides. Trop de mauvaises réponses / ne fonctionnent pas là-bas ...

            Process proc;
            try {
                //create a bash window
                proc = Runtime.getRuntime().exec("/bin/bash");
                if (proc != null) {
                       BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
                       PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
                       BufferedReader err = new BufferedReader(new InputStreamReader(
                       proc.getErrorStream()));
                       //input into the bash window
                       out.println("cd /my_folder");
                       out.println("rm *.jar");
                       out.println("svn co path to repo");
                       out.println("mvn compile package install");
                       out.println("exit");
                       String line;
                        System.out.println("----printing output-----");
                          while ((line = in.readLine()) != null) {
                             System.out.println(line);
                          }
                          while((line = err.readLine()) != null) {
                             //read errors
                          }
                          proc.waitFor();
                          in.close();
                          out.close();
                          err.close();
                          proc.destroy();
                }

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.