Was macht „3> & 1 1> & 2 2> & 3“ in einem Skript?

Antworten:

77

Die Zahlen sind Dateideskriptoren und nur die ersten drei (beginnend mit Null) haben eine standardisierte Bedeutung:

0 - stdin
1 - stdout
2 - stderr

Jede dieser Zahlen in Ihrem Befehl bezieht sich auf einen Dateideskriptor. Sie können einen Dateideskriptor entweder mit in eine Datei >umleiten oder mit in einen anderen Dateideskriptor umleiten>&

Der 3>&1in Ihrer Kommandozeile wird einen neuen Dateideskriptor erstellen und umleiten, zu 1welchem STDOUT. Leiten Sie 1>&2nun den Dateideskriptor 1 nach STDERRund 2>&3den Dateideskriptor 2 nach 3 um STDOUT.

Also im Grunde haben Sie gewechselt STDOUTund STDERR, das sind die Schritte:

  1. Erstellen Sie eine neue FD 3 und zeigen Sie auf die FD 1
  2. Leiten Sie Dateideskriptor 1 zu Dateideskriptor 2 um. Wenn der Dateideskriptor nicht in 3 gespeichert worden wäre, würden wir das Ziel verlieren.
  3. Leiten Sie Dateideskriptor 2 zu Dateideskriptor 3 um. Jetzt werden die Dateideskriptoren eins und zwei umgeschaltet.

Wenn das Programm nun etwas zum Dateideskriptor 1 druckt, wird es zum Dateideskriptor 2 und umgekehrt gedruckt.

Ulrich Dangel
quelle
Sie haben gesagt, dass "3> & 1 in Ihrer Befehlszeile einen neuen Dateideskriptor erstellt und ihn zu 1 umleitet, was STDOUT ist". Aber bedeutet 1 nicht STDIN?
sofs1
19

Es tauscht stdoutund stderr.

>namebedeutet, dass die Ausgabe in eine Datei umgeleitet wird name.

>&numberbedeutet, dass die Ausgabe an den Dateideskriptor umgeleitet wird number.

Das &wird also benötigt, um der Shell mitzuteilen, dass Sie einen Dateideskriptor und keinen Dateinamen meinen.

Ein Dateideskriptor ist eine Zahl, die auf eine bereits geöffnete Datei verweist. Die Standardeingaben beziehen sich 0auf die Standardeingabe, die 1Standardausgabe oder den 2Standardfehler. Sie können auch eine beliebige andere Zahl verwenden, die einen neuen Dateideskriptor erstellt, genau wie beim Erstellen einer neuen Variablen mit var=value.

Standardmäßig werden sowohl Dateideskriptor 1als auch 2Gehe zu ausgeführt /dev/tty. Wenn Sie also somecommand 3>&1 1>&2 2>&3eine neue Shell ausführen , ändert sich nichts (außer Sie haben jetzt einen Dateideskriptor mit der Nummer 3).

Aber wenn es irgendwo früher im Skript eine Umleitung mit exec (zB exec 2>error.log) ausführt oder das Skript mit einer Befehlszeile einschließlich Umleitung (zB ./thescript 2>error.log) ausgeführt wird, dann werden stdout und stderr ausgetauscht.

In Ihrem speziellen Fall ist der Befehl, der seine stdout und stderr getauscht hat das ist dialog. Wenn ich auf die Manpage schaue , sehe ich

Some widgets, e.g., checklist, will write text to dialog's output.
Normally that is the standard error

Vielleicht möchte die Person, die das Skript geschrieben hat,, dass dialogdie Ausgabe stdoutstatt aus stderrirgendeinem Grund an sie gesendet wird.

Siehe auch Reihenfolge der Weiterleitungen

Mikel
quelle
1

Der Drehbuchautor definierte fd 3 wie folgt:

exec 3<> File.txt

Öffnen Sie "File.txt" und weisen Sie ihm fd 3 zu. Maximale Dateideskriptoren: 255

read -n 4 <&3

Nur 4 Zeichen lesen.

echo -n . >&3

Schreiben Sie dort einen Dezimalpunkt.

exec 3>&-

Schließen Sie fd 3.

cat File.txt

==> 1234.67890

Jonathan Jackson
quelle