Reihenfolge der Weiterleitungen

29

Ich verstehe nicht ganz, wie der Computer diesen Befehl liest.

cat file1 file2 1> file.txt 2>&1

Wenn ich das verstehe, 2>&1leiten Sie Standardfehler einfach zur Standardausgabe um.

Nach dieser Logik lautet der Befehl für mich wie folgt:

  1. Dateien verketten file1und file2.

  2. senden stdoutvon dieser Operation an file.txt.

  3. senden stderran stdout.

  4. Ende?

Ich bin nicht sicher, was der Computer macht. Nach meiner Logik sollte der Befehl lauten

cat file1 file2 2>&1 > file.txt

aber das ist nicht richtig.

iDontKnowBetter
quelle

Antworten:

46

Ich finde es einfacher, mir Aufgaben zu überlegen.

  • > ist wie =
  • & ist wie $

Du beginnst mit

1 = /dev/tty
2 = /dev/tty

dann 1> file.txt 2>&1tut dein erstes Beispiel,

1 = file.txt
2 = $1           # and currently $1 = file.txt

Ich lasse dich mit

1 = file.txt
2 = file.txt

Wenn Sie es anders gemacht haben, beginnen Sie wieder mit

1 = /dev/tty
2 = /dev/tty

dann 2>&1 > file.txttut

2 = $1           # and currently $1 = /dev/tty
1 = file.txt

Das Endergebnis ist also

1 = file.txt
2 = /dev/tty

und du hast nur umgeleitet stdout, nicht stderr.

Mikel
quelle
Ich verstehe die Analogie, aber es ist verwirrend - wofür steht das $?
Eliran Malka,
In einer Zuweisung wie var=$othervar, $stellt den Namen der Variablen auf der rechten Seite. In einer Umleitung wie 2>&1, &stellt die Dateideskriptor Nummer auf der rechten Seite. Ich sage, Sie können sich vorstellen, dass "Datei 2 gleich Datei 1" ist. (Es gibt jedoch zwei Arten von Gleichheit: <bedeutet "zum Lesen" und >bedeutet "zum Schreiben".)
Mikel
12

Die Reihenfolge der Umleitung ist wichtig und sollte von links nach rechts gelesen werden .

Zum Beispiel: command 2>&1 >somefilebedeutet:

  1. Leiten Sie stderr(nämlich 2) zum aktuellen Ziel stdout(an diesem Punkt zum Terminal) um.
  2. Dann wechseln stdoutSie zu somefile.

In diesem Fall wird stderrzum Terminal und stdoutzu einer Datei gewechselt, was Sie wahrscheinlich nicht wollen.

Auf der anderen Seite command >somefile 2>&1bedeutet:

  1. Weiterleiten stdoutansomefile
  2. Weiterleiten stderran dasselbe Ziel wie stdout( somefile).

In diesem letzten Fall beides stderrund stdoutlos somefile, das ist wohl was du willst.

Amelio Vazquez-Reina
quelle
4
cat file1 file2 1> file.txt 2>&1

>& Eigentlich bedeutet duplizieren, verwendet es den Systemaufruf dup, um einen neuen Dateideskriptor auf eine bereits geöffnete Datei abzubilden.

Sie müssen also (tatsächlich) zuerst die neue Standardausgabe öffnen, bevor Sie sagen "und stderr zu der aktuell eingestellten Standardausgabe umleiten".

X Tian
quelle
das ist fantastisch! Ich habe mich darüber gewundert &. Könnten Sie einige Verweise auf diese Syntax oder - noch besser - einige gute Ressourcen zum oben genannten dup-System beifügen?
Eliran Malka
1
'man dup' dokumentiert den Systemaufruf.
X Tian
macht Sinn :) Danke
Eliran Malka