Ich habe gerade angefangen zu lernen, wie alles eine Datei TM unter Linux ist, was mich gefragt hat, was passieren würde, wenn ich buchstäblich aus / dev / stdout lese:
$ cat /dev/stdout
^C
$ tail /dev/stdout
^C
( ^C
Ich töte das Programm, nachdem es hängt).
Wenn ich es mit versuche vim
, erhalte ich die undenkbare Meldung: "/ dev / stdout" ist keine Datei. Keuchen!
Was gibt es also, warum erhalte ich Probleme oder Fehlermeldungen, wenn ich versuche, diese "Dateien" zu lesen?
Antworten:
Sie bekommen keine "Hangups" von
cat(1)
undtail(1)
sie blockieren nur das Lesen.cat(1)
wartet auf Eingabe und druckt sie aus, sobald eine vollständige Zeile angezeigt wird:Hier habe ich getippt
foo
Enterbar
EnterCTRL- D.tail(1)
Wartet auf die Eingabe und druckt sie nur aus, wenn sie Folgendes erkennen kannEOF
:Hier habe ich nochmal getippt
foo
Enterbar
EnterCTRL- D.Vim ist der einzige, der Ihnen einen Fehler gibt. Er tut das , weil es läuft
stat(2)
gegen/dev/stdout
, und es findet es nicht hatS_IFREG
Bit gesetzt./dev/stdout
ist eine Datei, aber keine reguläre Datei. Tatsächlich gibt es im Kernel einen Tanz, um ihm einen Eintrag im Dateisystem zu geben. Unter Linux:Auf OpenBSD:
Auf FreeBSD:
quelle
(Fast) alles ist eine Datei, aber nicht alles ist eine normale Datei. Es ist nicht sinnvoll, einen Texteditor für eine spezielle Datei aufzurufen, z. B. ein Verzeichnis, einen Netzwerk-Socket, eine serielle Schnittstelle usw.
Die Datei
/dev/stdout
kann abhängig von der Unix-Variante eines von mehreren Dingen sein:In jedem Fall wird beim Öffnen
/dev/stdout
und ähnlichen Dateien ein neuer Dateideskriptor erstellt, der derselben Datei zugeordnet ist, die die Anwendung bereits für Dateideskriptor 1 geöffnet hat. „Standardausgabe“ bedeutet Dateideskriptor 1, und es ist nur eine Konvention, dass dieser Dateideskriptor verwendet wird für die Ausgabe - der Kernel ist das egal.Wenn Sie ein Programm in einem Terminal ausführen, werden alle drei Standarddeskriptoren (0 = Standardeingabe, 1 = Standardausgabe, 2 = Standardfehler) auf dem Endgerät geöffnet. Beim Lesen von diesem Gerät werden vom Benutzer eingegebene Zeichen zurückgegeben, und beim Schreiben auf dieses Gerät wird Text im Terminalfenster angezeigt. (Bei einem Endgerät gibt es keine Standardmethode, um die angezeigte Ausgabe zu lesen oder Eingaben in diese zu injizieren.)
Wenn Sie ausführen
cat /dev/stdout
, geschieht genau das Gleiche wiecat /dev/stdin
odercat /dev/stderr
, da diese drei Dateideskriptoren mit derselben Datei verbunden sind: Sie werden angewiesencat
, vom Terminal zu lesen. Das ist es, wascat
ohne Argument auch tut.Wenn Sie ausgeführt haben
cat /dev/stdout >foo
,/dev/stdout
verweisen Sie auf die Dateifoo
- dieser Befehl entsprichtcat foo >foo
. Abhängig von dercat
Implementierung kann es entweder zu einem Fehler kommen (die GNU-Version beschwert sich darüber, dass „Eingabedatei Ausgabedatei ist“), oder es wird nichts unternommen, weil es aus derfoo
leeren Datei liest (>foo
nur abgeschnitten). Mit einer Versioncat
, die diesen Sonderfall nicht erkennt, wenn erfoo
nicht leer ist, würdecat /dev/stdout >>foo
oder das Äquivalentcat foo >>foo
den Inhalt der Datei auf unbestimmte Zeit an sich selbst anhängen.Wenn Sie ausführen
vim /dev/stdout
, beschwert es sich, weil es nicht weiß, wie ein Terminal bearbeitet werden soll (das macht einfach keinen Sinn).quelle
cat
undtail
suchen nach optionalem Inhalt, gefolgt von einem Dateiende./dev/stdout
bleibt offen, alsocat
undtail
schau einfach weiter.quelle