Was macht "2> & 1" in der Kommandozeile?

Antworten:

78

Das 1kennzeichnet die Standardausgabe (stdout). Das 2kennzeichnet Standardfehler (stderr).

So 2>&1sagt Standardfehler zu senden , wo immer die Standardausgabe als auch umgeleitet wird. Was, seitdem es gesendet /dev/nullwird, so etwas wie das Ignorieren von Ausgaben ist.

Chealion
quelle
2
Gibt es einen Grund, warum ein kaufmännisches Und vor der 1 steht, nicht aber vor der 2? Ich dachte, das & sei ein reserviertes Zeichen, um einen Job im Hintergrund auszuführen, aber ich denke, das ist nur dann der Fall, wenn das kaufmännische Und am Ende eines Befehls als langes Zeichen angezeigt wird ...?
Matt Huggins
8
Da 0(stdin), 1(stdout) und 2(stderr) tatsächlich Dateideskriptoren sind, benötigt die Shell ein kaufmännisches Und, das ihnen zur Umleitung vorangestellt wird. In diesem Fall wird der Dateideskriptor dupliziert, wodurch die beiden Informationsströme effektiv zusammengeführt werden.
Chealion
12
Stellen Sie sich das so vor: Wenn Sie nur "1" ohne kaufmännisches Und hätten, würde die Shell eine Datei mit dem Namen "1" erstellen und die stderr-Ausgabe an diese umleiten.
CarlF
1
Okay, wäre das dann alleine gültig? curl http://www.google.com 2>/dev/nullWoher weiß die Befehlszeile, dass die "2" hier "stderr" bedeutet und nicht der zweite Parameter ist, den ich an den Befehl "curl" übergebe?
Matt Huggins
1
@ Matt Huggins: Ja. Das würde stattdessen die gesamte Ausgabe von stderrdirekt an senden /dev/null. Sie können es in der Praxis sehen , indem Sie versuchen curl, curl 1>/dev/nullund curl 2>/dev/nullnur die Ausgabe Änderung zu sehen. Auch hier wird das kaufmännische Und nur für den Dateideskriptor benötigt, zu dem umgeleitet wird.
Chealion 18.11.09
23

tl; dr

Holen Sie sich http://www.google.comim Hintergrund und verwerfen Sie die stdoutund stderr.

curl http://www.google.com > /dev/null 2>&1 &

ist das gleiche wie

curl http://www.google.com > /dev/null 2>/dev/null &

Grundlagen

0, 1Und 2stellt die Standard - Datei Deskriptoren in POSIX - Betriebssystemen. Ein Dateideskriptor ist eine Systemreferenz auf (im Grunde) eine Datei oder einen Socket .

Das Erstellen eines neuen Dateideskriptors in C kann ungefähr so ​​aussehen:

fd = open("data.dat", O_RDONLY)

Die meisten Unix-Systembefehle nehmen eine Eingabe vor und geben das Ergebnis an das Terminal aus. curlwird holen, was an der angegebenen URL ist ( google dot com ) und das Ergebnis anzeigen stdout.

Locken Ergebnis

Umleitung

Wie Sie sagten <und >verwendet werden, um die Ausgabe von einem Befehl an einen anderen Ort, wie eine Datei, umzuleiten.

Zum Beispiel in ls > myfiles.txt, lswird der Inhalt des aktuellen Verzeichnisses und >leitet seine Ausgabe an myfiles.txt(wenn die Datei nicht vorhanden ist erstellt wird, sonst überschrieben, aber Sie verwenden können , >>statt >stattdessen an die Datei angehängt). Wenn Sie den obigen Befehl ausführen, werden Sie feststellen, dass im Terminal nichts angezeigt wird. Das bedeutet normalerweise Erfolg in Unix-Systemen. Aktivieren Sie diese Option cat myfiles.txt, um den Dateiinhalt auf dem Bildschirm anzuzeigen.

> / dev / null 2> & 1

Der erste Teil > /dev/nullleitet die stdout, dh curlAusgang s‘ /dev/null(mehr dazu im Voraus) und 2>&1leitet die stderrzu dem stdout(die gerade umgeleitet wurde /dev/nullalles so gesendet werden soll /dev/null).

Auf der linken Seite von 2>&1erfahren Sie, was umgeleitet wird, und auf der rechten Seite, wohin . Das &ist auf der rechten Seite verwendet , zu unterscheiden stdout (1)oder stderr (2)von Dateien mit dem Namen 1oder 2. Am 2>1Ende würde also eine neue Datei mit dem Namen (falls noch nicht vorhanden) erstellt 1und das stderrErgebnis dort abgelegt .

/ dev / null

/dev/nullist eine leere Datei, ein Mechanismus, mit dem alles verworfen wird, was darauf geschrieben wurde. So curl http://www.google.com > /dev/nullwird effektiv die curlAusgabe unterdrückt .

> / dev / null

Aber warum wird auf dem Terminal noch etwas angezeigt? Dies ist keine curl reguläre Ausgabe, sondern es werden Daten an gesendet stderr, die hier zur Anzeige des Fortschritts und von Diagnoseinformationen und nicht nur von Fehlern verwendet werden .

curl http://www.google.com > /dev/null 2>&1Ignoriert sowohl curldie Ausgabe- als auch die curlFortschrittsinformationen. Das Ergebnis ist, dass nichts auf dem Terminal angezeigt wird.

Endlich

Am &Ende teilen Sie der Shell mit, dass der Befehl als Job im Hintergrund ausgeführt werden soll . Dadurch kehrt die Eingabeaufforderung sofort zurück, während der Befehl asynchron hinter den Kulissen ausgeführt wird. Geben Sie jobsIhr Terminal ein, um die aktuellen Aufträge anzuzeigen. Hinweis : Dies ist verschieden von den Prozessen in dem System ausgeführt wird . Um diese zu sehen, geben Sie topdas Terminal ein.

Verweise

Jorge Bucaran
quelle
1
Dies ist eine der besten Antworten auf der gesamten Website aus der Sicht des Layouts. Gut gemacht!
OmarOthman
Eine Sache, die ich nicht verstehe, ist, warum Sie alles senden möchten /dev/null? Willst du nicht die Ergebnisse der curlzumindest irgendwo nützlich?
Skube
@skube Rechts. In diesem Fall ist mir nicht klar, warum der Benutzer sowohl stdout als auch stderr verwerfen möchte. OP wollte wahrscheinlich nur verstehen, was die Syntax bedeutete.
Jorge Bucaran
5

2bezieht sich auf STDERR. 2>&1sendet STDERR an denselben Speicherort wie 1(STDOUT).

John T
quelle
0

Ich verstehe wie folgt:

Wenn Sie nur die Ausgabe- und Fehlerinformationen des Befehls auf dem Bildschirm lesen möchten, schreiben Sie einfach: curl http://www.google.com

Und manchmal möchten Sie die Ausgabeinformationen für eine spätere Überprüfung in einer Datei anstelle des Terminalbildschirms speichern. Dann können Sie Folgendes schreiben: curl http://www.google.com > logfile

Auf diese Weise werden jedoch die StdErr-Informationen ausgelassen, da >nur das StdOut an umgeleitet wird logfile.

Wenn Sie sich also um die Fehlerinformationen des Befehls kümmern, sobald dieser nicht ausgeführt werden kann, müssen Sie StdOut mit StdErr kombinieren 2>&1(was bedeutet, dass StdErr in StdOut gefaltet wird), sodass die folgende Befehlszeile geschrieben werden kann: curl http://www.google.com > logfile2> & 1

YaOzI
quelle