Ausführen mehrerer Befehle in einer Zeile in der Shell


388

Angenommen, ich habe eine Datei /templates/appleund möchte

  1. lege es an zwei verschiedenen Stellen und dann
  2. Entfernen Sie das Original.

Also, /templates/applewird nach /templates/usedAND kopiert /templates/inuse und danach möchte ich das Original entfernen.

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

Ich möchte alles in einer Zeile erledigen, 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 das die richtige Syntax?

Antworten:


792

Sie verwenden |(Pipe), um die Ausgabe eines Befehls in einen anderen Befehl zu leiten. Was Sie suchen, ist ein &&Operator, der den nächsten Befehl nur ausführt, 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

Um (nicht erschöpfend) die Befehlsoperatoren / Trennzeichen von bash zusammenzufassen:

  • |pipes (pipelines) die Standardausgabe ( stdout) eines Befehls in die Standardeingabe eines anderen Befehls. Beachten Sie, dass stderrdas Standardziel weiterhin verwendet wird, unabhängig davon, was gerade passiert.
  • |&leitet beide stdoutund stderreinen Befehl in die Standardeingabe eines anderen. Sehr nützlich, verfügbar in Bash Version 4 und höher.
  • &&führt den rechten Befehl von &&nur aus, wenn der vorherige erfolgreich war.
  • ||führt den rechten Befehl ||nur aus, wenn der vorherige fehlgeschlagen ist.
  • ;führt den rechten Befehl von ;immer aus, unabhängig davon, ob der vorherige Befehl erfolgreich war oder fehlgeschlagen ist. Es set -esei denn, es wurde zuvor aufgerufen, was bashbei einem Fehler zum Fehlschlagen führt.

6
Upvoted. Offizielle Dokumentation gnu.org/software/bash/manual/bash.html#Lists
flow2k

78

Warum nicht cpzu Position 1, dann mvzu Position 2. Dadurch wird das Original "entfernt".

Und nein, es ist nicht die richtige Syntax. |wird verwendet, um die Ausgabe eines Programms zu "leiten" und in die Eingabe für das nächste Programm umzuwandeln. Was Sie wollen, ist ;, dass mehrere Befehle getrennt werden.

cp file1 file2 ; cp file1 file3 ; rm file1

Wenn Sie benötigen, dass die einzelnen Befehle erfolgreich sein MÜSSEN, bevor der nächste gestartet werden kann, verwenden Sie &&stattdessen:

cp file1 file2 && cp file1 file3 && rm file1

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


10

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


7

Eine andere Option ist die Eingabe Ctrl+V Ctrl+Jam Ende jedes Befehls.

Beispiel (ersetzen #durch Ctrl+V Ctrl+J):

$ echo 1#
echo 2#
echo 3

Ausgabe:

1
2
3

Dadurch werden die Befehle ausgeführt, unabhängig davon, ob die vorherigen fehlgeschlagen sind.

Gleich wie: echo 1; echo 2; echo 3

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

Beispiel (ersetzen #durch Ctrl+V Ctrl+J):

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

Ausgabe:

1
failed-command: command not found

In können zshSie auch Alt+Enteroder Esc+Enteranstelle von verwendenCtrl+V Ctrl+J


3

Versuche dies..

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


2

Die Verwendung von Rohren kommt mir komisch vor. Auf jeden Fall sollten Sie den logischen andBash-Operator verwenden:

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

Wenn die cpBefehle fehlschlagen, rmwird der nicht ausgeführt.

Oder Sie können eine ausführlichere Befehlszeile mit einer forSchleife und erstellen cmp.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.