GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Versuchen Sie, die Bash-Umleitungssyntax und ihre Ausgaben zu verstehen?

Ich bin neu bei Linux und versuche zu verstehen, wie Weiterleitungen funktionieren.

Ich habe verschiedene Syntaxen zum Umleiten von stdout getestet und stderr in dieselbe Datei, die nicht alle dieselben Ergebnisse liefern.

Wenn ich zum Beispiel versuche, 2 Dateien aufzulisten, die nicht existieren (file1 und file2 ) und 2, die dies tun (foo und fz ):

Syntax #1 (ohne Weiterleitung):

$ ls file1 foo fz file2

Hier ist die Ausgabe, die ich im Terminal bekomme:

ls: cannot access file1: No such file or directory
ls: cannot access file2: No such file or directory
foo  fz

Syntax #2:

Jetzt mit Weiterleitung:

$ ls file1 foo fz file2 > redirect 2>&1

Die redirect Datei enthält dasselbe wie das Ergebnis für Syntax #1:

ls: cannot access file1: No such file or directory
ls: cannot access file2: No such file or directory
foo
fz

Bei beiden obigen Syntaxen scheint die Shell also stderr auszugeben zuerst, dann stdout .

Syntax #3:

Wenn ich es jetzt mit einer der folgenden Syntaxen versuche:

$ ls file1 foo fz file2 > redirect 2> redirect

oder

$ ls file1 foo fz file2 2> redirect > redirect

Dann die redirect Datei wird dies enthalten:

foo
fz
nnot access file1: No such file or directory
ls: cannot access file2: No such file or directory

Hier sieht es wie stdout aus wird vor stderr gedruckt , aber dann sehen wir, dass der Anfang von stderr wird um die gleiche Anzahl von Zeichen „beschnitten“ wie stdout .

Die stdout ist 6 Zeichen lang (foo fz , Carriage Return inklusive), also die ersten 6 Zeichen des stderr (ls: ca ) wurden von stdout überschrieben .
Es scheint also tatsächlich stderr zu sein zuerst gedruckt wurde, und dass stdout wurde dann über stderr gedruckt anstatt daran angehängt zu werden.

Allerdings wäre es für mich sinnvoller gewesen, wenn stderr war vollständig gelöscht und durch stdout ersetzt , anstatt nur teilweise zu überschreiben.

Syntax #4:

Die einzige Möglichkeit, die ich gefunden habe, um Syntax #3 zu korrigieren, besteht darin, den Append-Operator zu stdout hinzuzufügen :

$ ls file1 foo fz file2 >> redirect 2> redirect

oder

$ ls file1 foo fz file2 2> redirect >> redirect

Was dasselbe erzeugt wie Syntax #2:

ls: cannot access file1: No such file or directory
ls: cannot access file2: No such file or directory
foo
fz

Dieser Artikel hier erklärt, dass Syntax Nr. 3 falsch ist (wahrscheinlich auch Syntax Nr. 4). Aber um der Argumentation willen:Warum ist Syntax #3 falsch? Was genau sagt es aus (oder nicht sagen) die Shell zu tun im Gegensatz zu Syntax #2?

Verwandte:Was ist der Unterschied zwischen $(…) und `…` in Bash?

Gibt es auch einen Grund, warum die Ausgabe immer stderr anzeigt vor stdout ?

Vielen Dank!

Akzeptierte Antwort:

Es ist genauso, als würden zwei Prozesse ausgeführt, um gleichzeitig in dieselbe Datei zu schreiben … schlechte Idee. Sie landen mit zwei verschiedenen geöffneten Dateihandles und Ihre Daten können verstümmelt werden (wie es in Nr. 3 oben der Fall ist). Die Verwendung von Syntax #2 ist korrekt; es macht eins Datei-Handle und zeigt sowohl stderr als auch stdout auf dieselbe Stelle.

Da stderr immer zuerst gedruckt wird, gibt es dafür keinerlei Regel. Ich vermute mit ls es liegt daran, dass ls muss jeden Eintrag im Verzeichnis überprüfen, bevor es tatsächlich feststellen kann, dass eine bestimmte Datei nicht existiert. Anstatt also N Durchläufe über die Verzeichnistabelle zu machen, macht es einen einzigen Durchlauf, prüft auf alle angegebenen Befehlszeilenargumente, meldet die Fehler und druckt die gefundenen Dateien. Andere Befehle können nach stdout auf stderr ausgegeben werden oder sogar zwischen ihnen wechseln.


Linux
  1. Pipes und Redirection in Linux - erklärt!

  2. Suchen und kopieren Sie die Datei mit Bash

  3. Extrahieren Sie den Basisnamen der Datei ohne Pfad und Erweiterung in Bash

  4. Beim Versuch, Bash unter Windows zu verwenden, wurde keine Meldung über installierte Distributionen angezeigt

  5. bash:leite stderr auf Datei und stdout + stderr auf Bildschirm um

Bash:In Datei schreiben

Bash-Quellbefehl

Bash:An Datei anhängen

Bash-Umleitung mit Beispielen erklärt

Shell-Scripting Teil 4 – Eingabe, Ausgabe und Umleitung

Was genau ist <() in bash (und =() in zsh)?