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 ; command2Erster
command1ausgeführt wird, im Vordergrund, und sobald es beendet ist,command2wird 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 & command2Hier
command1wird im Hintergrund gestartet undcommand2beginnt sofort im Vordergrund zu laufen, ohne aufcommand1zu warten zum Beenden.Ein Zeilenumbruch nach
command1ist 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 && command2Hier
command2wird nachcommand1ausgeführt fertig ist und nur wenncommand1war 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 fioder einfach
if command1; then command2; fiwenn 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 || command2Hier
command2wird nur ausgeführt, wenncommand1fehlgeschlagen (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 fioder 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 dentestDienstprogramm.! 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 | command2Jede Ausgabe, die von
command1ausgegeben 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.txtDas Obige führt
commandaus auf den Inhalt vonfile.txt. -
<>:wie oben, aber die Datei ist in Lesen+Schreiben geöffnet Modus statt schreibgeschützt :command <> file.txtWenn 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.txtDas Obige speichert die Ausgabe von
commandalsout.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.txtIm obigen Beispiel
>leitet die Standardausgabe und2>um leitet Standardfehler um. Die Ausgabe kann auch mit1>umgeleitet werden aber da dies die Vorgabe ist, die1wird normalerweise weggelassen und einfach als>geschrieben .Also, um
commandauszuführen auffile.txtund speichern Sie die Ausgabe inout.txtund alle Fehlermeldungen inerror.txtSie 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 -Coderset -o noclobber).command >| out.txtWenn
out.txtexistiert, die Ausgabe voncommandwird 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.txtWenn
out.txtexistiert, die Ausgabe voncommandwird 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.txtSowohl Standardfehler als auch Standardausgabe von
commandwird inout.txtgespeichert , überschreibt seinen Inhalt oder erstellt ihn, wenn er nicht existiert.command &>> out.txtWie oben, außer dass wenn
out.txtexistiert, die Ausgabe und der Fehler voncommandwird 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 portablemshverwendet werden Skripte. -
<<:Ein hier Dokument. Es wird oft verwendet, um mehrzeilige Zeichenketten zu drucken.command << WORD Text WORDHier
commandnimmt alles, bis es das nächste Vorkommen vonWORDfindet ,Textim obigen Beispiel als input . WährendWORDist oftEoFoder Variationen davon, es kann jede alphanumerische (und nicht nur) Zeichenfolge sein, die Sie mögen. WennWORDzitiert 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 ... WORDweiterleiten möchten direkt in einen anderen Befehl oder mehrere Befehle, müssen Sie die Pipe in die gleiche Zeile wie<< WORDsetzen , 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 <<< WORDWas auch immer als
WORDangegeben 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.