Unterschied zwischen 2> & -, 2> / dev / null, | &, &> / dev / null und> / dev / null 2> & 1

192

Ich suche nur den Unterschied zwischen

  • 2>&-
  • 2>/dev/null
  • |&
  • &>/dev/null
  • >/dev/null 2>&1

und ihre Portabilität mit non-Bourne shellswie tcsh, mkshusw.

Det
quelle
2
Beachten Sie, dass mksh zwar die &>GNU-Bash-Kompatibilität unterstützt, jedoch dringend davon abgeraten wird , da das Parsen die Semantik vorhandener POSIX-Skripte unterbrechen kann und mksh diese bereits im POSIX-Modus deaktiviert.
Mirabilos
Ich habe auch gesehen, ^ /dev/nullwas das macht?
Balupton

Antworten:

241

Zum Hintergrund:

  • a number 1 = standard out (dh STDOUT)
  • eine Zahl 2 = Standardfehler (dh STDERR)
  • Wenn eine Zahl nicht explizit angegeben wird, wird die Zahl 1 von der Shell übernommen (bash).

Lassen Sie uns zuerst die Funktion von diesen angehen. Informationen hierzu finden Sie im Advanced Bash-Scripting Guide .

Funktionen

2>&-

Die allgemeine Form von diesem ist M>&-, wobei "M" eine Dateideskriptornummer ist. Dies schließt die Ausgabe für jeden Dateideskriptor, auf den verwiesen wird, dh "M" .

2>/dev/null

Die allgemeine Form von diesem ist M>/dev/null, wobei "M" eine Dateideskriptornummer ist. Dadurch wird der Dateideskriptor "M" nach umgeleitet /dev/null.

2>&1

Die allgemeine Form von diesem ist M>&N, wo "M" & "N" Dateideskriptornummern sind. Es kombiniert die Ausgabe der Dateideskriptoren "M" und "N" in einem einzigen Stream.

|&

Dies ist nur eine Abkürzung für 2>&1 |. Es wurde in Bash 4 hinzugefügt.

&>/dev/null

Dies ist nur eine Abkürzung für >/dev/null 2>&1. Er leitet den Dateideskriptor 2 (STDERR) und den Deskriptor 1 (STDOUT) an um /dev/null.

>/dev/null

Dies ist nur eine Abkürzung für 1>/dev/null. Es leitet den Dateideskriptor 1 (STDOUT) weiter zu /dev/null.

Portabilität auf Nicht-Bash, TCSH, MKSH usw.

Ich habe mich nicht viel mit anderen Muscheln außerhalb von cshund befasst tcsh. Meine Erfahrung mit diesen 2 verglichen mit den Umleitungsoperatoren von bash ist, dass bash in dieser Hinsicht überlegen ist. Weitere Informationen finden Sie auf der tcsh-Manpage .

Von den Befehlen, nach denen Sie gefragt haben, werden keine direkt von csh / tcsh unterstützt. Sie müssten unterschiedliche Syntaxen verwenden, um ähnliche Funktionen zu erstellen.

slm
quelle
Wir haben einen Sieger. Aber so gibt es keinen Leistungsunterschied oder solche mit 2>&-vs 2>/dev/null(abgesehen davon 2>&-, dass einige "schlecht" geschriebene Programme nicht richtig verstehen )?
Det
3
Es sollte keinen Leistungsunterschied geben.
SLM
5
&>war bashvon Anfang an dabei (und bricht die Bourne- und POSIX-Kompatibilität, da es etwas anderes bedeutet, obwohl es unwahrscheinlich ist, dass es getroffen wird). >&und |&kommen von (t)csh(und es ist ihre einzige Möglichkeit, stderr umzuleiten). Sie waren zshvon Anfang an dabei und wurden erst kürzlich hinzugefügt bash. Siehe auch rcfür besser gestaltete Operatoren.
Stéphane Chazelas
1
Update: Über das Leistungsproblem, das auch hier bestätigt wird: unix.stackexchange.com/questions/163955/…
Det
1
Hallo @slm, danke für den Kontakt. Ich bin froh, dass sich mein Repo nicht geändert hat (+2-2=0). Nun zum Ausgabe-Teil, ich bearbeite nicht viel, aber in diesem Fall würde ich, weil es klarstellt, dass die Daten nach der Operation bei wären N. Ich habe Ihre Antwort durchgelesen und sie ist in jeder Hinsicht in Ordnung. Gerade diese kleine Zweideutigkeit hat mich zum Nachdenken gebracht, deshalb die Edition. Aber ok, Sie können es jederzeit wieder hinzufügen oder ablehnen. Ich hoffe, ich konnte den Punkt erklären. Mach weiter so.
Dr. Beco
11

Dies ist für die Umleitung der STDERR & STDOUT:

  • 2>/dev/null

    Leiten Sie STDERR nach / dev / null um (verhindern Sie, dass es auf der Konsole angezeigt wird)

  • |&

    Umleiten von STDERR und STDOUT zu STDIN des weitergeleiteten Befehls (cmd1 | & cmd2)

  • &>/dev/null

    Leiten Sie sowohl STDERR als auch STDOUT nach / dev / null um (auf der Konsole wird nichts angezeigt)

  • >/dev/null

    STDOUT nach / dev / null umleiten (nur STDERR wird auf der Konsole angezeigt)

  • 2>&-

    Dient zum Schließen eines mit der Umleitung verwendeten Dateideskriptors

Dies sind alle Standardumleitungsmethoden für die Bourne-Shells.

BriGuy
quelle
4
|&und &>/dev/nullsind nicht tragbar.
Chris Down
4

Betrachten Sie dies als Ergänzung zur ausgewählten Antwort. Vielleicht möchten Sie wissen, welche Formulare POSIX sind und welche nicht.

Es handelt sich um zwei POSIX-Formulare:

2.7.2 Ausgabe umleiten

Die zwei allgemeinen Formate zum Umleiten der Ausgabe sind:

[n]> Wort

[n]> | word

wobei das optionale n die Dateideskriptornummer darstellt. Wenn die Nummer weggelassen wird, bezieht sich die Umleitung auf die Standardausgabe (Dateideskriptor 1).

Die Ausgabeumleitung im Format '>' schlägt fehl, wenn die Option noclobber gesetzt ist (siehe Beschreibung von set -C) und die durch die Erweiterung von word angegebene Datei existiert und eine reguläre Datei ist. Andernfalls Umleitung mit '>' oder "> |" Formate müssen bewirken, dass die Datei, deren Name sich aus der Erweiterung des Wortes ergibt, erstellt und zur Ausgabe auf dem angegebenen Dateideskriptor oder, falls keiner angegeben ist, zur Standardausgabe geöffnet wird. Ist die Datei nicht vorhanden, wird sie erstellt. Andernfalls wird es nach dem Öffnen als leere Datei abgeschnitten.

-

2.7.6 Duplizieren eines Ausgabedateideskriptors

Der Umleitungsoperator:

[n]> & word

dupliziert einen Ausgabedateideskriptor von einem anderen oder schließt einen. Wenn das Wort eine oder mehrere Ziffern ergibt, wird der mit n bezeichnete Dateideskriptor oder die Standardausgabe, wenn n nicht angegeben ist, als Kopie des mit word bezeichneten Dateideskriptors erstellt. Stellen die Ziffern in Word keinen bereits zur Ausgabe geöffneten Dateideskriptor dar, tritt ein Umleitungsfehler auf. Siehe Folgen von Shell-Fehlern. Wenn word als '-' ausgewertet wird, wird der Dateideskriptor n oder die Standardausgabe geschlossen, wenn n nicht angegeben ist. Versuche, einen nicht geöffneten Dateideskriptor zu schließen, stellen keinen Fehler dar. Wenn word einen anderen Wert ergibt, ist das Verhalten nicht spezifiziert.

Deshalb:

Function      POSIX-compat    POSIX 
2>&-          Yes             close 
2>/dev/null   Yes             redir
2>&1          Yes             dup 
|&            No              
&>/dev/null   No
>/dev/null    Yes             redir
>&/dev/null   ?               ?dup

Die letzte Zeile ist nicht in der ursprünglichen Frage, aber es funktioniert ohne Beanstandung in Bash. (Funktioniert auch mit / dev / tty anstelle von / dev / null).

Craig Hicks
quelle
1
Ich möchte immer mehr wissen.
Det