509 Stimmen

Das Ausführen mehrerer Befehle in einer Zeile in der Shell

Sagen wir, ich habe eine Datei /templates/apple und ich möchte

  1. es an zwei verschiedenen Orten platzieren und dann
  2. das Original entfernen.

Also wird /templates/apple in /templates/used UND /templates/inuse kopiert und danach möchte ich das Original entfernen.

Ist cp der beste Weg, um dies zu tun, gefolgt von rm? Oder gibt es einen besseren Weg?

Ich möchte alles in einer Zeile machen, also denke ich, dass es ungefähr so aussehen würde:

cp /templates/apple /templates/used | cp /templates/apple /templates/inuse | rm /templates/apple

Ist dies die richtige Syntax?

1014voto

Maxim Egorushkin Punkte 125210

Du verwendest das | (Pipe) Zeichen, um die Ausgabe eines Befehls in einen anderen Befehl umzuleiten. Was du suchst, ist der && Operator, um den nächsten Befehl nur auszuführen, wenn der vorherige erfolgreich war:

cp /templates/apple /templates/used && cp /templates/apple /templates/inuse && rm /templates/apple

Oder

cp /templates/apple /templates/used && mv /templates/apple /templates/inuse

Zusammenfassend (nicht erschöpfend) die Befehlsoperatoren/-trenner von Bash:

  • | leitet die Standardausgabe (stdout) eines Befehls in die Standardeingabe eines anderen Befehls um. Beachte, dass stderr weiterhin in sein Standardziel geht, was auch immer das sein mag.
  • |& leitet sowohl stdout als auch stderr eines Befehls in die Standardeingabe eines anderen Befehls um. Sehr nützlich, verfügbar ab Bash Version 4.
  • && führt den Befehl auf der rechten Seite von && nur aus, wenn der vorherige erfolgreich war.
  • || führt den Befehl auf der rechten Seite von || nur aus, wenn der vorherige fehlgeschlagen ist.
  • ; führt den Befehl auf der rechten Seite von ; immer aus, unabhängig davon, ob der vorherige Befehl erfolgreich war oder fehlgeschlagen ist. Es sei denn, vorher wurde set -e aufgerufen, was dazu führt, dass bash bei einem Fehler fehlschlägt.

14 Stimmen

Hochgewertet. Official documentation gnu.org/software/bash/manual/bash.html#Lists

116voto

Marc B Punkte 347897

Warum nicht cp zum Ort 1, dann mv zum Ort 2. Dadurch wird das "Entfernen" des Originals erledigt.

Und nein, das ist nicht die richtige Syntax. | wird verwendet, um die Ausgabe von einem Programm in die Eingabe für das nächste Programm umzuwandeln. Was du möchtest, ist ;, das mehrere Befehle trennt.

cp datei1 datei2 ; cp datei1 datei3 ; rm datei1

Wenn du möchtest, dass die einzelnen Befehle ERFOLGREICH sein MÜSSEN, bevor der nächste gestartet werden kann, dann würdest du stattdessen && verwenden:

cp datei1 datei2 && cp datei1 datei3 && rm datei1

Auf diese Weise wird, wenn einer der cp-Befehle fehlschlägt, das rm nicht ausgeführt.

12voto

glenn jackman Punkte 221248

Beachten Sie, dass cp A B; rm A genau mv A B ist. Es wird auch schneller sein, da Sie die Bytes nicht tatsächlich kopieren müssen (vorausgesetzt das Ziel befindet sich auf demselben Dateisystem), sondern nur die Datei umbenennen müssen. Also möchten Sie cp A B; mv A C

9voto

Eyal Levin Punkte 13427

Eine weitere Option besteht darin, am Ende jeder Befehlsfolge Strg+V Strg+J einzugeben.

Beispiel (ersetzen Sie # durch Strg+V Strg+J):

$ echo 1#
echo 2#
echo 3

Ergebnis:

1
2
3

Das führt die Befehle aus, unabhängig davon, ob vorherige fehlgeschlagen sind.

Gleichbedeutend mit: echo 1; echo 2; echo 3

Wenn Sie die Ausführung bei fehlgeschlagenen Befehlen beenden möchten, fügen Sie am Ende jeder Zeile außer der letzten ein && hinzu.

Beispiel (ersetzen Sie # durch Strg+V Strg+J):

$ echo 1 &&#
failed-command &&#
echo 2

Ergebnis:

1
failed-command: Befehl nicht gefunden

In zsh können Sie auch Alt+Enter oder Esc+Enter anstelle von Strg+V Strg+J verwenden

4voto

Renaud Punkte 8703

Die Verwendung von Pipes erscheint mir seltsam. Wie auch immer, du solltest den logischen und Bash Operator verwenden:

$ cp /templates/apfel /templates/benutzt && cp /templates/apfel /templates/inbenutzung && rm /templates/apfels

Wenn die cp Befehle fehlschlagen, wird das rm nicht ausgeführt.

Oder du kannst eine komplexere Befehlszeile mit einer for Schleife und cmp erstellen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X