Ich habe diese Zeile in einem Skript gesehen:
DEVICE=`dialog --inputbox "Festplatten-Laufzeit auslesen. Gebe Sie das
gewünschte Device an: " 0 70 "" 3>&1 1>&2 2>&3`
Was ist
3>&1 1>&2 2>&3
machen? Ich weiß, dass 1 = stdout und 2 = stderr, aber wofür sind das 3
und das &
?
Antwort1
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 also auf einen Dateideskriptor. Sie können einen Dateideskriptor entweder auf eine Datei umleiten mit >
oder auf einen anderen Dateideskriptor mit>&
Das 3>&1
in Ihrer Befehlszeile erstellt einen neuen Dateideskriptor und leitet ihn um 1
zu STDOUT
. Jetzt 1>&2
wird der Dateideskriptor 1 umgeleitet zu STDERR
und 2>&3
der Dateideskriptor 2 wird umgeleitet zu 3 , was ist STDOUT
.
Sie haben also im Wesentlichen gewechselt STDOUT
. STDERR
Dies sind die Schritte:
- Erstellen Sie ein neues FD 3 und verweisen Sie es auf FD 1
- Leiten Sie den Dateideskriptor 1 zum Dateideskriptor 2 um. Wenn wir den Dateideskriptor 3 nicht gespeichert hätten, würden wir das Ziel verlieren.
- Leiten Sie Dateideskriptor 2 auf Dateideskriptor 3 um. Jetzt sind Dateideskriptor eins und zwei vertauscht.
Wenn das Programm jetzt etwas in den Dateideskriptor 1 druckt, wird es in den Dateideskriptor 2 gedruckt und umgekehrt.
Antwort2
Es ist ein Austausch stdout
und stderr
.
>name
bedeutet, die Ausgabe in eine Datei umzuleiten name
.
>&number
bedeutet, die Ausgabe zum Dateideskriptor umzuleiten number
.
Daher &
müssen Sie der Shell mitteilen, dass Sie einen Dateideskriptor und keinen Dateinamen meinen.
Ein Dateideskriptor ist eine Nummer, die sich auf eine bereits geöffnete Datei bezieht. Die Standarddeskriptoren sind 0
für die Standardeingabe, 1
die Standardausgabe oder 2
die Standardfehlerausgabe. Sie können auch jede andere Nummer verwenden, die einen neuen Dateideskriptor erstellt, genau wie wenn Sie mit eine neue Variable erstellen var=value
.
Standardmäßig gehen sowohl der Dateideskriptor 1
als auch 2
zu /dev/tty
. Wenn Sie es also in einer neuen Shell ausführen somecommand 3>&1 1>&2 2>&3
, ändert sich nichts (außer, dass Sie jetzt einen Dateideskriptor mit der Nummer 3 haben).
Wenn jedoch irgendwo früher im Skript eine Umleitung mit exec erfolgt (z. B. exec 2>error.log
) oder das Skript mit einer Befehlszeile einschließlich Umleitung ausgeführt wird (z. B. ./thescript 2>error.log
), dann bewirkt das Vertauschen von stdout und stderr etwas.
In Ihrem speziellen Fall ist der Befehl, dessen stdout und stderr vertauscht sind dialog
, . Wenn man sich seinemanpage, Ich verstehe
Some widgets, e.g., checklist, will write text to dialog's output.
Normally that is the standard error
daher möchte die Person, die das Skript geschrieben hat, aus irgendeinem Grund möglicherweise, dass die Ausgabe von an und nicht dialog
an geht .stdout
stderr
Siehe auchReihenfolge der Weiterleitungen
Antwort3
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
Antwort4
Ich habe den Zweck des Dateideskriptors und des Befehls "3> & 1 1> & 2 2> & 3" anhand des folgenden Beispiels verstanden
#!/bin/bash
#it's normal case fd environment
echo test 1> afile.txt
echo "Test no 1"
cat afile.txt
echo "Test no 1"
echo test 2> afile.txt
echo "Test no 2"
cat afile.txt
echo "Test no 2"
echo test 1> afile.txt
echo "Test no 3"
cat afile.txt
echo "Test no 3"
echo test 2> afile.txt
echo "Test no 4"
cat afile.txt
echo "Test no 4"
echo > afile.txt
echo "------------------------------------------------------------------------"
#it's relocate filedescriptor and cause not problem, and cause error(std error)
var=
var=$(echo test 3>&1 1>&2 2>&3)
echo "Test no 5"
#cat afile.txt
echo $var
echo "Test no 5"
var=
var=$(echo test 3>&1 1>&2 2>&3)
echo "Test no 6"
#cat afile.txt
echo $var
echo "Test no 6"
var=
var=$(echo test 3>&1 1>&2 2>&3)
echo "Test no 7"
#cat afile.txt
echo $var
echo "Test no 7"
var=
var=$(echo test 3>&1 1>&2 2>&3)
echo "Test no 8"
#cat afile.txt
echo $var
echo "Test no 8"
Wenn Sie dieses Beispiel ausführen, sehen Sie, dass die Dateideskriptoren neu angeordnet und die Ausgabe geändert werden.