Note that the order of redirections is significant. For example, the command
ls > dirlist 2>&1
directs both standard output and standard error to the file dirlist,
while the command
ls 2>&1 > dirlist
directs only the standard output to file dirlist, because the
standard error was duplicated from the standard output before the standard
output was redirected to dirlist.
Nun, dieser letzte Teil verwirrt mich. In diesem Fall würde ein Standardfehler auf dem Terminal ausgegeben und ein STDOUT in die Dirlistendatei verschoben. Das würde passieren, aber so verstehe ich das Handbuch nicht.
Es scheint, als sollte es heißen "weil der Standardfehler von der Standardausgabe dupliziert wurde, NACHDEM die Standardausgabe zur Verzeichnisliste umgeleitet wurde". Wenn STDERR an STDOUT gesendet wurde, bevor STDOUT an eine Datei weitergeleitet wurde, enthält die Datei dann nicht STDOUT AND STDERR?
Kann das bitte jemand für mich klären? Ist es nur ein schlechtes Leseverständnis von meiner Seite? Die Verwendung des Wortes Vervielfältigung erscheint mir in diesem Zusammenhang etwas seltsam. Vielleicht wirft mich das.
bash
shell
io-redirection
Gregg Leventhal
quelle
quelle
a = 1; b = a; a = 2
Sie erwartena == 2 && b == 1
, wahr zu sein. Die Umleitung2>&1
ähnelt derb = a
Zuweisung - es handelt sich um einen Wert, nicht um einen Verweis.2>&1
heiratet Dateideskriptor 2 nicht für alle Ewigkeit mit Dateideskriptor 1 - es sind immer noch 2 verschiedene Dateideskriptoren, die zufällig auf dieselbe Datei verweisen.Antworten:
Vervielfältigung ist hier wirklich der wichtige Teil.
Mal sehen, wohin die Dateideskriptoren vor der Umleitung gehen. Dies ist normalerweise das aktuelle Terminal, zB:
Wenn wir jetzt
ls -l
ohne Umleitung anrufen , gehen Ausgabe- und Fehlermeldungen zu meinem Endgerät unter/dev/pts/1
.Wenn wir das zuerst
STDOUT
in eine Datei umleiten (ls -l > dirlist
), sieht es so aus:Wenn wir dann
STDERR
zu einem Duplikat vonSTDOUT
's file descriptor (ls -l > dirlist 2>&1
) umleiten , gehen wirSTDERR
zu einem Duplikat von/home/bon/dirlist
:Wenn wir zuerst
STDERR
zu einem Duplikat vonSTDOUT
's file descriptor (ls -l 2>&1
) umleiten würden :und dann
STDOUT
zu einer Datei (ls -l 2>&1 > dirlist
), würden wir dies bekommen:Hier geht
STDERR
es noch zum Terminal.Sie sehen, die Reihenfolge in der Manpage ist korrekt.
Umleitung testen
Jetzt können Sie das selbst testen. Mit sehen
ls -l /proc/$$/fd/
Sie, woSTDOUT
(mit fd 1) undSTDERR
(mit fd 2) der aktuelle Prozess abläuft:Lassen Sie uns ein kleines Shell-Skript erstellen, das zeigt, wohin Ihre Dateideskriptoren zeigen. Auf diese Weise erhalten wir beim Aufrufen immer den Status
ls
, einschließlich der Umleitung von der aufrufenden Shell.(Mit CtrlDsenden Sie ein Dateiende und beenden so das
cat
Lesen des Befehls vonSTDIN
.)Rufen Sie nun dieses Skript mit verschiedenen Kombinationen von Umleitungen auf:
Sie sehen, dass die Dateideskriptoren 1 (für
STDOUT
) und 2 (fürSTDERR
) variieren. Zum Spaß könnten Sie auch umleitenSTDIN
und das Ergebnis sehen:(Frage an den Leser: Wo steht der Dateideskriptor 255? ;-))
quelle
Nein, das Handbuch ist richtig.
Wenn 1 zuerst auf das Terminal und 2 auch auf das Terminal zeigt, dann:
Die Auswertung der Umleitung erfolgt von links nach rechts.
Es wird also ZUERST ausgewertet
2>&1
und kopiert, worauf fd zeigte1
(dh den Dateideskriptor vonthe terminal
normalerweise / dev / tty), in fd2
.An diesem Punkt zeigt fd
2
nun auf die Stelle , auf die fd1
früher zeigte (the terminal
) zeigte.Und DANN wertet es den
1>somewhere
Teil aus und kopiert damit den Dateideskriptor vonsomewhere
in fd1
(an diesem Punkt zeigt fd1
nun aufsomewhere
und fd zeigt2
immer noch aufthe terminal
).Es wird also tatsächlich 1 in "irgendwo" und 2 in das Terminal gedruckt, da 2 von 1 dupliziert wurde, BEVOR 1 geändert wurde.
Die andere Reihenfolge:
Leitet zuerst fd
1
nach umsomewhere
und kopiert dann die gleiche Referenz in fd 2, so dass am Ende 2 auch auf zeigtsomewhere
. Sie sind aber von nun an nicht mehr "verknüpft". Jeder kann weiterhin separat umgeleitet werden.Ex:
Am Ende davon zeigt fd
1
aufsomewhere
und fd2
ist auf gerichtet/dev/null
Übliche Namen für fd
1
sind STDOUT (Standardausgabe), und der übliche Name für fd2
ist STDERR (Standardfehler, da er häufig zur Anzeige von Fehlern ohne Beeinträchtigung von STDOUT verwendet wird).quelle
cmd 1>somewhere 2>&1 ; exec 2>/dev/null
: Nach der Ausführung wurden nur 2 nach / dev / null umgeleitet (1 geht immer noch nach "irgendwo"). Ich brauche Hilfe, um einen Weg zu finden, um zu sagen, "was 1 Punkte" statt "der fd 1", aber ... da das auch verwirrend ist ...Ich denke, der verwirrende Teil hier ist das Missverständnis, dass die Umleitung von stderr zu stdout die beiden Streams tatsächlich verbindet.
Eine durchaus vernünftige Idee, aber was passiert, wenn Sie schreiben,
2>&1
ist, dass stderr einen Blick auf das wirft, was stdout schreibt, und an denselben Ort selbst schreibt. Wenn Sie stdout anschließend anweisen, an eine andere Stelle zu schreiben, hat dies keine Auswirkung auf das Ziel von stderr, das bereits verschoben wurde.Ich denke, es ist ein bisschen eingängig, aber so funktioniert es. Stellen Sie ein, wo Sie zuerst schreiben möchten, und sagen Sie dann allen, dass Sie mich kopieren möchten. Hoffe das klärt ...
quelle
VERVIELFÄLTIGUNG...
ist wichtig, aber eher in dem Sinne, dass es die Quelle vieler Verwirrung ist . Das ist ganz einfach. Diese Antwort ist nur eine "radikale" Illustration.
Die akzeptierte Antwort ist gut, aber zu lang und betont "Duplikation".
Das Q endet weise mit:
Ich benutze die Bash-Notation und definiere die Variablen "eins" und "zwei" als Dateihandles "1" und "2". Der (Ausgabe-) Umleitungsoperator
>
ist eine Zuweisung=
.&
und$
Mittelwert von.Die man bash Beispiele (mit Standard "1" hinzugefügt)
werden:
und
Und selbst das ist für mich und einige andere, denke ich, nicht automatisch. In der ersten Zeile werden Sie mit
$one
und$two
beide mit "dirlist" belassen. Natürlich.Die zweite Zeile beginnt mit einer unnützen Zuweisung. Beide beginnen per Definition mit "TTY" (ein bisschen symbolisch) als Richtung ; Durch diese Zuweisung wird kein Wert geändert, und bei Variablen wie bei Dateihandles ist nichts magisch verknüpft. Die Variable
two
wird von den folgenden Punkten nicht beeinflusstone=dirlist
. Natürlich nicht.Jemand hier (vor 6 Jahren) hat "point to" anstelle von "copy" oder "duplicate" vorgeschlagen und dann festgestellt: Das wäre auch verwirrend.
Diese Duplikation oder Zeigersemantik wird nicht einmal benötigt. Vielleicht ist es das kaufmännische Und, das mehr Aufmerksamkeit benötigt. Der "Wert von" Operator / Token / was auch immer.
Wenn - und nur wenn - Sie nach einer Möglichkeit suchen, eine überraschende Auftragsnummer auf Ihrer Konsole zu erhalten , dann eine Meldung "erledigt" und als Bonus eine Datei mit dem Namen "2", dann gehen Sie folgendermaßen vor:
Es liest sich natürlich als " copy" / "duplicate" 1 zu 2 und dann beide zusammen auf null . Aber die Idee ist falsch und auch die Syntax. (aber kein Syntaxfehler, es ist gültig)
Der richtige Weg, dies zu planen, besteht darin, eine der beiden auf null umzuleiten und dann die ANDERE an dieselbe Stelle umzuleiten:
(die führende "1" kann weggelassen werden)
(OK das acc. A ist nicht zu lang, aber es ist zu viel von einer Liste - oder: sehr gute Visualisierung, nicht so gute Erklärung)
quelle