Wie (und warum) verwenden Sie stderr zum Lesen und Schreiben?
12
Nach dieser Antwort von schily , lessliest Navigationsbefehle von stderr , wenn es zu öffnen nicht in der Lage ist /dev/tty.
Dies scheint rätselhaft, da ich noch nie etwas gesehen habe, das in den Stderr-Stream eines anderen Programms geschrieben wurde, und ich weiß nicht, wie ich das überhaupt erreichen würde.
Was ist der Zweck von stderr, sowohl zum Lesen als auch zum Schreiben offen zu sein? Und wenn dies nützlich ist, wie nutze ich es auf modernen Systemen? (Gibt es eine arkane Syntax, um zum Beispiel etwas in stderr anstatt in stdin zu leiten?)
Ich war zuerst überrascht. Nach dem Lesen der Antworten und einer kleinen Untersuchung scheint es jedoch einfach zu sein. Also hier ist was ich gefunden habe. (Am Ende gab es keine Überraschung.)
Vor der Umleitung werden stdin, stdout und stderr erwartungsgemäß mit demselben Gerät verbunden.
#ctrl-alt-delor:~$
#↳ ll /dev/std*
lrwxrwxrwx 1 root root 15 Jun 3 20:58 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jun 3 20:58 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Jun 3 20:58 /dev/stdout -> /proc/self/fd/1
#ctrl-alt-delor:~$
#↳ ll /proc/self/fd/*
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/0 -> /dev/pts/12
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/1 -> /dev/pts/12
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/2 -> /dev/pts/12
Daher wird nach den meisten Umleitungen (dh wenn stderr) nicht umgeleitet. stderr ist weiterhin mit dem Terminal verbunden. Daher kann es gelesen werden, um Tastatureingaben zu erhalten.
Das einzige, was verhindert, dass die Dateien in unerwarteter Richtung verwendet werden, ist die Konvention, und die Pipes sind unidirektional.
Versuchen Sie es mit einem anderen Beispiel:
cat | less
Dies geht nach einer Seite schief, wenn lessversucht wird, das Terminal zu lesen (dies ist keine Überraschung, ebenso wie catdas Lesen des Terminals).
/dev/ttyist mysteriöser, es ist keine Verbindung in /proc/self.
Wenn Sie sich anmelden, werden stdin, stdout und stderr mit dem Terminal verbunden, von dem aus Sie sich anmelden. Genauer gesagt wird das tty normalerweise geöffnet, und stdout und stderr sind das Ergebnis von zwei dup(2)Operationen im ersten Dateideskriptor. Dies ermöglicht das Lesen von stderr, um Eingaben vom Termnal zu erhalten.
Wie in der anderen Antwort erwähnt, lesen Programme von stderr, um eine interaktive Antwort auf eine Frage zu erhalten.
Da ein Benutzer nicht wissen kann, unter welchen Umständen ein Programm aus stderr liest, ist es ein nutzloser Versuch, absichtlich Daten aus einem anderen Programm in stderr zu schreiben.
Beachten Sie, dass heutige Programme normalerweise zuerst versuchen, /dev/ttystderr nur zu öffnen und zu verwenden, falls dies nicht funktioniert.
Programme, die normalerweise nur aus stderr lesen, wurden seit vor 1979 nie mehr geändert, und solche Programme enthalten normalerweise Konstrukte wie:
int i 1;
oder
i =* 2;
das werden von modernen C-Compilern nicht akzeptiert. Daher ist es höchst unwahrscheinlich, dass Sie heute ein Programm finden, das niemals geöffnet wird /dev/tty, sondern interaktive Antworten von stderr liest.
Wenn ich also richtig verstehe, stellt die Shell eine Verbindung stderrzum tty her, wenn sie stdinumgeleitet wird (über eine Pipe oder andere Mittel)? Oder verbindet sich einfach immer stderrmit dem tty?
Draconis
1
Wenn Sie sich anmelden, ist stderr mit Ihrem Anmeldeterminal verbunden.
schily
2
i =+ 1ist vollkommen gültig C und ist gleich i = (+1). Zugegeben, der erstere ist ein netter Kandidat für den hinterhältigen C-Wettbewerb.
G. Sliepen
1
OK, es kann sein, dass nur eine Warnung erstellt wird. Ich habe den Code 1977 von C in etwas anderes geändert.
/dev/tty
sehen, diese Frage .Wenn Sie sich anmelden, werden stdin, stdout und stderr mit dem Terminal verbunden, von dem aus Sie sich anmelden. Genauer gesagt wird das tty normalerweise geöffnet, und stdout und stderr sind das Ergebnis von zwei
dup(2)
Operationen im ersten Dateideskriptor. Dies ermöglicht das Lesen von stderr, um Eingaben vom Termnal zu erhalten.Wie in der anderen Antwort erwähnt, lesen Programme von stderr, um eine interaktive Antwort auf eine Frage zu erhalten.
Da ein Benutzer nicht wissen kann, unter welchen Umständen ein Programm aus stderr liest, ist es ein nutzloser Versuch, absichtlich Daten aus einem anderen Programm in stderr zu schreiben.
Beachten Sie, dass heutige Programme normalerweise zuerst versuchen,
/dev/tty
stderr nur zu öffnen und zu verwenden, falls dies nicht funktioniert.Programme, die normalerweise nur aus stderr lesen, wurden seit vor 1979 nie mehr geändert, und solche Programme enthalten normalerweise Konstrukte wie:
oder
das werden von modernen C-Compilern nicht akzeptiert. Daher ist es höchst unwahrscheinlich, dass Sie heute ein Programm finden, das niemals geöffnet wird
/dev/tty
, sondern interaktive Antworten von stderr liest.quelle
stderr
zum tty her, wenn siestdin
umgeleitet wird (über eine Pipe oder andere Mittel)? Oder verbindet sich einfach immerstderr
mit dem tty?i =+ 1
ist vollkommen gültig C und ist gleichi = (+1)
. Zugegeben, der erstere ist ein netter Kandidat für den hinterhältigen C-Wettbewerb.