Ich sehe oft Tutorials online, die verschiedene Befehle mit verschiedenen Symbolen verbinden. Zum Beispiel:
command1 | command2
command1 & command2
command1 || command2
command1 && command2
Andere scheinen Befehle mit Dateien zu verbinden:
command1 > file1
command1 >> file1
Was sind diese Dinge? Wie werden sie genannt? Was machen Sie? Gibt es noch mehr davon?
Meta-Thread zu dieser Frage..
Akzeptierte Antwort:
Diese werden Shell-Operatoren genannt und ja, es gibt noch mehr davon. Ich werde einen kurzen Überblick über die gebräuchlichsten unter den beiden Hauptklassen geben, Kontrolloperatoren und Umleitungsoperatoren, und wie sie in Bezug auf die Bash-Shell funktionieren.
A. Steueroperatoren
POSIX-Definition
In der Shell-Befehlssprache ein Token, das eine Kontrollfunktion ausführt.
Es ist eines der folgenden Symbole:
& && ( ) ; ;; <newline> | ||
Und |&
in bash.
Ein !
ist nicht ein Steueroperator, sondern ein reserviertes Wort. Es wird zu einem logischen NOT [Negationsoperator] innerhalb von arithmetischen Ausdrücken und innerhalb von Testkonstrukten (wobei immer noch ein Leerzeichen als Trennzeichen erforderlich ist).
A.1 Terminatoren auflisten
-
;
:Führt einen Befehl nach dem anderen aus, unabhängig vom Ergebnis des ersten.command1 ; command2
Erster
command1
ausgeführt wird, im Vordergrund, und sobald es beendet ist,command2
wird ausgeführt.Ein Zeilenumbruch, der nicht in einem String-Literal oder nach bestimmten Schlüsselwörtern steht, ist nicht entspricht dem Semikolon-Operator. Eine Liste von
;
begrenzte einfache Befehle ist immer noch eine Liste – wie in der Shell muss der Parser weiterhin die einfachen Befehle einlesen, die einem;
folgen begrenzten einfachen Befehl vor der Ausführung, während ein Zeilenumbruch eine ganze Befehlsliste – oder eine Liste von Listen – begrenzen kann. Der Unterschied ist subtil, aber kompliziert:Da die Shell keinen vorherigen Imperativ zum Einlesen von Daten nach einem Zeilenumbruch hat, markiert der Zeilenumbruch einen Punkt, an dem die Shell beginnen kann, die einfachen Befehle auszuwerten, die sie bereits eingelesen hat, während ein;
Semikolon nicht. -
&
:Dadurch wird ein Befehl im Hintergrund ausgeführt, sodass Sie in derselben Shell weiterarbeiten können.command1 & command2
Hier
command1
wird im Hintergrund gestartet undcommand2
beginnt sofort im Vordergrund zu laufen, ohne aufcommand1
zu warten zum Beenden.Ein Zeilenumbruch nach
command1
ist optional.
A.2 Logische Operatoren
-
&&
:Wird verwendet, um UND-Listen zu erstellen, ermöglicht es Ihnen, einen Befehl nur auszuführen, wenn ein anderer erfolgreich beendet wurde.command1 && command2
Hier
command2
wird nachcommand1
ausgeführt fertig ist und nur wenncommand1
war erfolgreich (wenn sein Beendigungscode 0 war). Beide Befehle werden im Vordergrund ausgeführt.Dieser Befehl kann auch geschrieben werden
if command1 then command2 else false fi
oder einfach
if command1; then command2; fi
wenn der Rückgabestatus ignoriert wird. -
||
:Wird verwendet, um ODER-Listen zu erstellen, ermöglicht es Ihnen, einen Befehl nur dann auszuführen, wenn ein anderer erfolglos beendet wurde.command1 || command2
Hier
command2
wird nur ausgeführt, wenncommand1
fehlgeschlagen (wenn es einen anderen Exit-Status als 0 zurückgegeben hat). Beide Befehle werden im Vordergrund ausgeführt.Dieser Befehl kann auch geschrieben werden
if command1 then true else command2 fi
oder kürzer
if ! command1; then command2; fi
.Beachten Sie, dass
&&
und||
sind linksassoziativ; siehe Vorrang der logischen Shell-Operatoren &&, || für weitere Informationen. -
!
:Dies ist ein reserviertes Wort, das als „nicht“-Operator fungiert (muss aber ein Trennzeichen haben), das verwendet wird, um den Rückgabestatus eines Befehls zu negieren – geben Sie 0 zurück, wenn der Befehl einen Status ungleich Null zurückgibt, geben Sie 1 zurück, wenn er den Status 0 zurückgibt Auch ein logisches NICHT für dentest
Dienstprogramm.! command1 [ ! a = a ]
Und ein echter NOT-Operator in arithmetischen Ausdrücken:
$ echo $((!0)) $((!23)) 1 0
A.3 Pipe-Operator
-
|
:Der Pipe-Operator, er übergibt die Ausgabe eines Befehls als Eingabe an einen anderen. Ein aus dem Pipe-Operator erstellter Befehl wird als Pipeline bezeichnet.command1 | command2
Jede Ausgabe, die von
command1
ausgegeben wird wird als Eingabe ancommand2
übergeben . -
|&
:Dies ist eine Abkürzung für2>&1 |
in bash und zsh. Es übergibt sowohl die Standardausgabe als auch die Standardfehler eines Befehls als Eingabe für einen anderen.command1 |& command2
A.4 Andere Listenzeichensetzung
;;
wird nur verwendet, um das Ende einer Case-Anweisung zu markieren. Ksh, bash und zsh unterstützen auch ;&
um zum nächsten Fall durchzufallen und ;;&
(nicht in ATT ksh), um weitere Fälle zu testen.
(
und )
werden verwendet, um Befehle zu gruppieren und sie in einer Subshell zu starten. {
und }
gruppieren Sie auch Befehle, aber starten Sie sie nicht in einer Subshell. Siehe diese Antwort für eine Diskussion der verschiedenen Arten von Klammern, Klammern und geschweiften Klammern in der Shell-Syntax.
B. Umleitungsoperatoren
POSIX-Definition des Umleitungsoperators
In der Shell-Befehlssprache ein Token, das eine Umleitungsfunktion ausführt. Es ist eines der folgenden Symbole:
< > >| << >> <& >& <<- <>
Mit diesen können Sie die Ein- und Ausgabe Ihrer Befehle steuern. Sie können überall innerhalb eines einfachen Befehls erscheinen oder einem Befehl folgen. Umleitungen werden in der Reihenfolge verarbeitet, in der sie erscheinen, von links nach rechts.
-
<
:Gibt Eingaben für einen Befehl.command < file.txt
Das Obige führt
command
aus auf den Inhalt vonfile.txt
. -
<>
:wie oben, aber die Datei ist in Lesen+Schreiben geöffnet Modus statt schreibgeschützt :command <> file.txt
Wenn die Datei nicht existiert, wird sie erstellt.
Dieser Operator wird selten verwendet, da Befehle im Allgemeinen nur lesen von ihrer stdin, obwohl es in einer Reihe von spezifischen Situationen nützlich sein kann.
-
>
:Leitet die Ausgabe eines Befehls in eine Datei.command > out.txt
Das Obige speichert die Ausgabe von
command
alsout.txt
. Wenn die Datei existiert, wird ihr Inhalt überschrieben und wenn sie nicht existiert, wird sie erstellt.Dieser Operator wird auch oft verwendet, um auszuwählen, ob etwas in die Standardfehler- oder Standardausgabe gedruckt werden soll:
command >out.txt 2>error.txt
Im obigen Beispiel
>
leitet die Standardausgabe und2>
um leitet Standardfehler um. Die Ausgabe kann auch mit1>
umgeleitet werden aber da dies die Vorgabe ist, die1
wird normalerweise weggelassen und einfach als>
geschrieben .Also, um
command
auszuführen auffile.txt
und speichern Sie die Ausgabe inout.txt
und alle Fehlermeldungen inerror.txt
Sie würden Folgendes ausführen:command < file.txt > out.txt 2> error.txt
-
>|
:Macht dasselbe wie>
, überschreibt aber das Ziel, selbst wenn die Shell so konfiguriert wurde, dass sie das Überschreiben verweigert (mitset -C
oderset -o noclobber
).command >| out.txt
Wenn
out.txt
existiert, die Ausgabe voncommand
wird seinen Inhalt ersetzen. Wenn es nicht existiert, wird es erstellt. -
>>
:Macht dasselbe wie>
, außer dass, wenn die Zieldatei existiert, die neuen Daten angehängt werden.command >> out.txt
Wenn
out.txt
existiert, die Ausgabe voncommand
wird daran angehängt, nachdem was schon drin ist. Wenn es nicht existiert, wird es erstellt. -
>&
:(gemäß POSIX-Spezifikation), wenn es von Ziffern umgeben ist (1>&2
) oder-
auf der rechten Seite (1>&-
) leitet entweder nur einen weiter Dateideskriptor oder schließt sie (>&-
).Ein
>&
gefolgt von einer Dateideskriptornummer ist eine portable Möglichkeit, einen Dateideskriptor umzuleiten, und>&-
ist eine portable Möglichkeit, einen Dateideskriptor zu schließen.Wenn die rechte Seite dieser Weiterleitung eine Datei ist, lesen Sie bitte den nächsten Eintrag.
-
>&
,&>
,>>&
und&>>
:(siehe auch oben) Leite sowohl Standardfehler als auch Standardausgabe um, jeweils ersetzend oder anhängend.command &> out.txt
Sowohl Standardfehler als auch Standardausgabe von
command
wird inout.txt
gespeichert , überschreibt seinen Inhalt oder erstellt ihn, wenn er nicht existiert.command &>> out.txt
Wie oben, außer dass wenn
out.txt
existiert, die Ausgabe und der Fehler voncommand
wird daran angehängt.Der
&>
Variante stammt ausbash
, während>&
Variante kommt von csh (Jahrzehnte früher). Beide stehen in Konflikt mit anderen POSIX-Shell-Operatoren und sollten nicht in portablemsh
verwendet werden Skripte. -
<<
:Ein hier Dokument. Es wird oft verwendet, um mehrzeilige Zeichenketten zu drucken.command << WORD Text WORD
Hier
command
nimmt alles, bis es das nächste Vorkommen vonWORD
findet ,Text
im obigen Beispiel als input . WährendWORD
ist oftEoF
oder Variationen davon, es kann jede alphanumerische (und nicht nur) Zeichenfolge sein, die Sie mögen. WennWORD
zitiert wird, wird der Text im Here-Dokument wörtlich behandelt und es werden keine Erweiterungen (z. B. auf Variablen) durchgeführt. Wenn es nicht in Anführungszeichen steht, werden Variablen erweitert. Weitere Einzelheiten finden Sie im Bash-Handbuch.Wenn Sie die Ausgabe von
command << WORD ... WORD
weiterleiten möchten direkt in einen anderen Befehl oder mehrere Befehle, müssen Sie die Pipe in die gleiche Zeile wie<< WORD
setzen , Sie können es nicht nach dem abschließenden WORD oder in der folgenden Zeile einfügen. Zum Beispiel:command << WORD | command2 | command3... Text WORD
-
<<<
:Here-Strings, ähnlich wie here-Dokumente, aber für eine einzelne Zeile gedacht. Diese existieren nur in der Unix-Portierung oder rc (woher sie stammt), zsh, einigen Implementierungen von ksh, yash und bash.command <<< WORD
Was auch immer als
WORD
angegeben wird erweitert und sein Wert wird als Eingabe ancommand
übergeben . Dies wird häufig verwendet, um den Inhalt von Variablen als Eingabe an einen Befehl zu übergeben. Zum Beispiel:$ foo="bar" $ sed 's/a/A/' <<< "$foo" bAr # as a short-cut for the standard: $ printf '%sn' "$foo" | sed 's/a/A/' bAr # or sed 's/a/A/' << EOF $foo EOF
Ein paar andere Operatoren (>&-
, x>&y
x<&y
) kann verwendet werden, um Dateideskriptoren zu schließen oder zu duplizieren. Einzelheiten dazu finden Sie im entsprechenden Abschnitt Ihres Shell-Handbuchs (hier zum Beispiel für bash).
Das deckt nur die gängigsten Operatoren von Bourne-ähnlichen Shells ab. Manche Shells haben ein paar zusätzliche eigene Umleitungsoperatoren.
Ksh, bash und zsh haben auch Konstrukte <(…)
, >(…)
und =(…)
(Letzteres in zsh
nur). Dies sind keine Umleitungen, sondern Prozesssubstitutionen.