Esegui combinare più comandi Linux in una riga


329

Sto cercando di unire più comandi Linux in una riga per eseguire l'operazione di distribuzione. Per esempio

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

Risposte:


717

Se si desidera eseguire ciascun comando solo se il precedente ha avuto esito positivo, combinarli utilizzando l' &&operatore:

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

Se uno dei comandi fallisce, tutti gli altri comandi che seguono non verranno eseguiti.

Se si desidera eseguire tutti i comandi indipendentemente dal fatto che i precedenti abbiano avuto esito negativo o meno, separarli con punto e virgola:

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

Nel tuo caso, penso che tu voglia il primo caso in cui l'esecuzione del comando successivo dipende dal successo del precedente.

Puoi anche inserire tutti i comandi in uno script ed eseguirlo invece:

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

(Le barre rovesciate alla fine della riga servono per impedire alla shell di pensare che la riga successiva sia un nuovo comando; se si omettono le barre rovesciate, è necessario scrivere l'intero comando in un'unica riga.)

Salvalo in un file, ad esempio myscript, e rendilo eseguibile:

chmod +x myscript

Ora puoi eseguire quello script come altri programmi sulla macchina. Ma se non lo si inserisce in una directory elencata nella PATHvariabile di ambiente (ad esempio /usr/local/bino su alcune distribuzioni Linux ~/bin), sarà necessario specificare il percorso di quello script. Se si trova nella directory corrente, lo si esegue con:

./myscript

I comandi nello script funzionano allo stesso modo dei comandi nel primo esempio; il comando successivo viene eseguito solo se il precedente ha avuto esito positivo. Per l'esecuzione incondizionata di tutti i comandi, è sufficiente elencare ciascun comando sulla propria riga:

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

38
Per i lettori futuri: è possibile utilizzare anche al ||posto del punto e virgola o &&se si desidera eseguire il comando successivo solo se l'ultimo non è riuscito. Come nel provare questo, e se fallisce, provalo.
DeVadder

3
Hm, i punti e virgola non sempre funzionano. Ad esempio, ls >/dev/null & ; echo $!genera un errore.
Ciao Angelo

1
E se volessi eseguire il primo comando in background e un altro in primo piano .. Sto provando questo tail -f my.log & && ./myscriptche non funziona .. per favore, suggerisci.
OverrockSTAR

4
@Pareshkumar Con bash, puoi fare: { tail -f my.log & } && ./myscriptTuttavia, nota che &&qui è inutile, poiché il primo lavoro viene eseguito in background e quindi il secondo lavoro non può conoscere il risultato, poiché entrambi i lavori verranno avviati contemporaneamente. Quindi potresti anche scrivere:{ tail -f my.log & }; ./myscript
Nikos C.

Cosa succede se ho bisogno delle sudoautorizzazioni per eseguire uno dei comandi? Dovrei mettere sudoall'inizio di tutti i comandi o solo in quello che ne ha bisogno? Come posso passare la password a quel comando in modo che venga eseguita correttamente?
Drubio,

46

Ho scoperto che usando; separare i comandi funziona solo in primo piano. per esempio :

cmd1; cmd2; cmd3 & - eseguirà solo cmd3in background, mentre cmd1 && cmd2 && cmd3 &- eseguirà l'intera catena in background SE non ci sono errori.

Per soddisfare l'esecuzione incondizionata, l'uso della parentesi risolve questo:

(cmd1; cmd2; cmd3) & - eseguirà la catena di comandi in background, anche se qualsiasi passaggio fallisce.


1
La e commerciale finale (&) nei tuoi esempi era intenzionale? In tal caso, a cosa serve?
Technophile,

5
@Technophile Esegue un comando in background
Oak Chantosa,

1
Una risposta semplice, breve e diretta, dovresti usare i siti web StackExchange più spesso Dean. Grazie per il tuo contributo.
CPHPython

10

Puoi separare i tuoi comandi usando un punto e virgola:

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

Era quello che volevi dire?


3

Per eseguirli tutti in una volta, è possibile utilizzare il tasto della tubazione "|" così:

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

1
La pipeline viene utilizzata per fornire l'output del comando al comando successivo come input. Ad esempio: X | Y -> L'output del comando X funzionerà come input per il comando Y
Arpan Saini,

2

Se si desidera eseguire tutti i comandi, che il precedente sia eseguito o meno, è possibile utilizzare il punto e virgola (;) per separare i comandi.

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

Se si desidera eseguire il comando successivo solo se il comando precedente ha esito positivo, è possibile utilizzare && per separare i comandi.

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

Nel tuo caso, l'esecuzione di comandi consecutivi sembra dipendere dai comandi precedenti, quindi usa il secondo esempio, cioè usa && per unire i comandi.


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

non è lo stesso dello script OP, per favore spiega: se un comando fallisce, lo script si interrompe
Gilles Quenot,

4
Inoltre, è possibile utilizzare il cmd1 || cmd2separatore se è necessario cmd2eseguire solo se lo cmd1stato diverso da zero è stato restituito alla shell e si può usare cmd1 ; cmd2se si desidera eseguire entrambi i comandi indipendentemente dal loro stato di ritorno.
Victor Sorokin,

@sputnick Dovrebbe essere, l'ho appena incollato e concatenato i comandi con &&
Mark Stevens,

3
@MarkStevens È un'implementazione migliore ma non otterrà gli stessi risultati come se i comandi fossero eseguiti in sequenza, penso che questo sia ciò che significa sputnick.
andrux,

1

Qual è l'utilità di una sola e commerciale? Questa mattina, ho creato un programma di avvio nel pannello XFCE (in Manjaro + XFCE) per avviare 2 gestori password contemporaneamente:

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

Ma non funziona come voglio. IE, la prima app si avvia ma la seconda inizia solo quando la precedente è chiusa

Tuttavia, ho scoperto che (con una sola e commerciale):

sh -c "keepassx & password-gorilla"

e funziona come voglio ora ...


1
La e commerciale agisce come un terminatore di comando simile a ;, tranne per il fatto che questo mette in primo piano il comman, cioè la shell non vedrà il suo output.
Sergiy Kolodyazhnyy,

-1

Puoi usare come il seguente codice;

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

Funziona...


-1

Trovo molte risposte per questo tipo di domanda fuorviante

Modificato da questo post: https://www.webmasterworld.com/linux/3613813.htm

Il codice seguente creerà la finestra bash e funziona esattamente come una finestra bash. Spero che questo ti aiuti. Troppe risposte errate / non funzionanti là fuori ...

            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();
            }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.