Führen Sie mehrere Linux-Befehle in einer Zeile aus

329

Ich versuche, mehrere Linux-Befehle in einer Zeile zusammenzuführen, um den Bereitstellungsvorgang auszuführen. Zum Beispiel

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

Antworten:

716

Wenn Sie jeden Befehl nur ausführen möchten, wenn der vorherige erfolgreich war, kombinieren Sie sie mit dem &&Operator:

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

Wenn einer der Befehle fehlschlägt, werden alle anderen darauf folgenden Befehle nicht ausgeführt.

Wenn Sie alle Befehle ausführen möchten, unabhängig davon, ob die vorherigen fehlgeschlagen sind oder nicht, trennen Sie sie durch Semikolons:

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

In Ihrem Fall möchten Sie den ersten Fall, in dem die Ausführung des nächsten Befehls vom Erfolg des vorherigen abhängt.

Sie können auch alle Befehle in ein Skript einfügen und stattdessen Folgendes ausführen:

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

(Die Backslashes am Ende der Zeile verhindern, dass die Shell denkt, dass die nächste Zeile ein neuer Befehl ist. Wenn Sie die Backslashes weglassen, müssen Sie den gesamten Befehl in eine einzelne Zeile schreiben.)

Speichern Sie das beispielsweise in einer Datei myscriptund machen Sie sie ausführbar:

chmod +x myscript

Sie können dieses Skript jetzt wie andere Programme auf dem Computer ausführen. Wenn Sie es jedoch nicht in einem Verzeichnis ablegen, das in Ihrer PATHUmgebungsvariablen aufgeführt ist (z. B. /usr/local/binoder auf einigen Linux-Distributionen ~/bin), müssen Sie den Pfad zu diesem Skript angeben. Wenn es sich im aktuellen Verzeichnis befindet, führen Sie es aus mit:

./myscript

Die Befehle im Skript funktionieren genauso wie die Befehle im ersten Beispiel. Der nächste Befehl wird nur ausgeführt, wenn der vorherige erfolgreich war. Für die bedingungslose Ausführung aller Befehle listen Sie einfach jeden Befehl in einer eigenen Zeile auf:

#! /bin/sh
cd /my_folder
rm *.jar
svn co path to repo
mvn compile package install
Nikos C.
quelle
38
Für zukünftige Leser: Sie können auch ||anstelle von Semikolon verwenden oder &&wenn der nächste Befehl nur ausgeführt werden soll, wenn der letzte fehlgeschlagen ist. Versuchen Sie dies, und versuchen Sie es, wenn dies fehlschlägt.
DeVadder
3
Hm, Semikolons funktionieren nicht immer. ZB ls >/dev/null & ; echo $!löst einen Fehler aus.
Hi-Angel
1
Und was ist, wenn ich den ersten Befehl im Hintergrund und einen anderen im Vordergrund ausführen möchte? Ich versuche dies, tail -f my.log & && ./myscriptwas nicht funktioniert. Bitte schlagen Sie vor.
OverrockSTAR
4
@Pareshkumar Mit bash können Sie Folgendes tun: { tail -f my.log & } && ./myscriptBeachten Sie jedoch, dass das &&hier nutzlos ist, da der erste Job im Hintergrund ausgeführt wird und der zweite Job das Ergebnis nicht kennen kann, da beide Jobs gleichzeitig gestartet werden. Sie können also genauso gut schreiben:{ tail -f my.log & }; ./myscript
Nikos C.
Was ist, wenn ich sudoBerechtigungen benötige , um einen der Befehle auszuführen? Sollte ich das sudoam Anfang aller Befehle setzen oder nur in das, was es braucht? Wie kann ich das Passwort an diesen Befehl übergeben, damit er ordnungsgemäß ausgeführt wird?
Drubio
46

Ich habe das mit gefunden; Befehle zu trennen funktioniert nur im Vordergrund. z.B :

cmd1; cmd2; cmd3 & - wird nur cmd3im Hintergrund ausgeführt, während cmd1 && cmd2 && cmd3 &- die gesamte Kette im Hintergrund ausgeführt wird, wenn keine Fehler vorliegen.

Um eine bedingungslose Ausführung zu gewährleisten, löst die Verwendung von Klammern Folgendes:

(cmd1; cmd2; cmd3) & - führt die Befehlskette im Hintergrund aus, auch wenn ein Schritt fehlschlägt.

Dean
quelle
1
War das nachfolgende kaufmännische Und (&) in Ihren Beispielen beabsichtigt? Wenn ja, wofür ist es?
Technophile
5
@ Technophile Es ist ein Hintergrundbefehl
auszuführen
1
Eine einfache, kurze und direkte Antwort: Sie sollten StackExchange-Websites häufiger verwenden, Dean. Danke für deinen Beitrag.
CPHPython
10

Sie können Ihre Befehle mit einem Semikolon trennen:

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

Meinten Sie das?

Andrux
quelle
3

Um sie alle gleichzeitig auszuführen, können Sie den Pipe-Line-Schlüssel "|" verwenden. wie so:

$ cd /my_folder | rm *.jar | svn co path to repo | mvn compile package install
Kelly Poore
quelle
1
Die Pipeline wird verwendet, um die Ausgabe Ihres Befehls als Eingabe an den nächsten Befehl zu übergeben. Zum Beispiel: X | Y -> X Befehlsausgabe wird als Eingabe für Y Befehl
Arpan Saini
2

Wenn Sie alle Befehle ausführen möchten, unabhängig davon, ob der vorherige ausgeführt wird oder nicht, können Sie die Befehle mit einem Semikolon (;) trennen.

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

Wenn Sie den nächsten Befehl nur ausführen möchten, wenn der vorherige Befehl erfolgreich ist, können Sie die Befehle mit && trennen.

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

In Ihrem Fall scheint die Ausführung aufeinanderfolgender Befehle von den vorherigen Befehlen abzuhängen. Verwenden Sie daher das zweite Beispiel, dh verwenden Sie &&, um die Befehle zu verbinden.

Prabhu
quelle
1
cd /my_folder && rm *.jar && svn co path to repo && mvn compile package install
Mark Stevens
quelle
Es ist nicht dasselbe wie das OP-Skript. Bitte erläutern Sie: Wenn ein Befehl fehlschlägt, wird das Skript
abgebrochen
4
Darüber hinaus können Sie das cmd1 || cmd2Trennzeichen verwenden, wenn Sie cmd2es nur ausführen müssen , wenn der cmd1Status ungleich Null an die Shell zurückgegeben wird, und Sie können es verwenden, cmd1 ; cmd2wenn Sie beide Befehle unabhängig von ihrem Rückgabestatus ausführen möchten.
Victor Sorokin
@sputnick Es sollte sein, ich habe es gerade eingefügt und die Befehle mit &&
Mark Stevens
3
@MarkStevens Es ist eine bessere Implementierung, aber es werden nicht die gleichen Ergebnisse erzielt, als ob die Befehle nacheinander ausgeführt würden. Ich denke, das hat Sputnick bedeutet.
Andrux
1

Was ist der Nutzen eines einzigen kaufmännischen Und? Heute Morgen habe ich im XFCE-Bedienfeld (in Manjaro + XFCE) einen Starter gestartet, um zwei Kennwortmanager gleichzeitig zu starten:

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

Aber es funktioniert nicht so wie ich will. IE, die erste App startet, aber die zweite startet erst, wenn die vorherige geschlossen ist

Ich fand jedoch Folgendes (mit nur einem kaufmännischen Und):

sh -c "keepassx & password-gorilla"

und es funktioniert wie ich will jetzt ...

Nettlebay AP
quelle
1
Das ;kaufmännische Und fungiert ähnlich wie der Befehlsabschluss , mit der Ausnahme, dass das Komman im Hintergrund vorangestellt wird, dh die Shell sieht die Ausgabe nicht.
Sergiy Kolodyazhnyy
arbeitet für mich, danke.
DaSqy Stc
-1

Sie können den folgenden Code verwenden:

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

Es klappt...

Deniz Güzel
quelle
-1

Ich finde viele Antworten auf diese Art von Frage irreführend

Geändert von diesem Beitrag: https://www.webmasterworld.com/linux/3613813.htm

Der folgende Code erstellt ein Bash-Fenster und funktioniert genau wie ein Bash-Fenster. Hoffe das hilft. Zu viele falsche / nicht funktionierende Antworten da draußen ...

            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();
            }
wwjih123
quelle