Ich bin ziemlich verwirrt mit dem Zweck dieser drei Dateien. Wenn mein Verständnis richtig ist, stdin
ist die Datei, in die ein Programm in seine Anforderungen schreibt, um eine Aufgabe im Prozess auszuführen, stdout
die Datei, in die der Kernel seine Ausgabe schreibt, und der Prozess, der ihn auffordert, auf die Informationen zuzugreifen, und stderr
die Datei, in die welche alle Ausnahmen eingegeben werden. Beim Öffnen dieser Dateien, um zu überprüfen, ob diese tatsächlich auftreten, habe ich nichts gefunden, was darauf hindeutet!
Was ich wissen möchte, ist, was genau der Zweck dieser Dateien ist, absolut heruntergekommene Antwort mit sehr wenig Fachjargon!
Antworten:
Standardeingabe - Dies ist das Dateihandle , das Ihr Prozess liest, um Informationen von Ihnen zu erhalten.
Standardausgabe - Ihr Prozess schreibt normale Informationen in dieses Dateihandle.
Standardfehler - Ihr Prozess schreibt Fehlerinformationen in dieses Dateihandle.
Das ist ungefähr so niedergeschlagen, wie ich es schaffen kann :-)
Das ist natürlich meistens konventionell. Nichts hindert Sie daran, Ihre Fehlerinformationen in die Standardausgabe zu schreiben, wenn Sie dies wünschen. Sie können die drei Dateihandles sogar vollständig schließen und Ihre eigenen Dateien für E / A öffnen.
Wenn Ihr Prozess startet, sollten diese Handles bereits geöffnet sein und er kann nur von ihnen lesen und / oder darauf schreiben.
Standardmäßig sind sie wahrscheinlich mit Ihrem Endgerät verbunden (z. B.
/dev/tty
), aber mithilfe von Shells können Sie Verbindungen zwischen diesen Handles und bestimmten Dateien und / oder Geräten (oder sogar Pipelines zu anderen Prozessen) herstellen, bevor Ihr Prozess beginnt (einige davon) Die möglichen Manipulationen sind ziemlich klug.Ein Beispiel ist:
welches wird:
my_prog
.inputfile
als Standardeingabe (Dateihandle 0).errorfile
als Standardfehler (Dateihandle 2).grep
.my_prog
dem Standardeingang von hinzugrep
.Zu Ihrem Kommentar:
Es ist, weil sie keine normalen Dateien sind. Während UNIX alles irgendwo als Datei in einem Dateisystem darstellt, ist dies auf den niedrigsten Ebenen nicht der Fall. Die meisten Dateien in der
/dev
Hierarchie sind entweder Zeichen- oder Blockgeräte, praktisch ein Gerätetreiber. Sie haben keine Größe, aber eine Haupt- und eine Nebengerätenummer.Wenn Sie sie öffnen, sind Sie eher mit dem Gerätetreiber als mit einer physischen Datei verbunden, und der Gerätetreiber ist intelligent genug, um zu wissen, dass separate Prozesse separat behandelt werden sollten.
Gleiches gilt für das Linux-
/proc
Dateisystem. Dies sind keine echten Dateien, sondern streng kontrollierte Gateways zu Kernelinformationen.quelle
xyz >xyz.out
schreibt Ihre Standardausgabe in eine physische Datei, die von anderen Prozessen gelesen werden kann.xyz | grep something
verbindetxyz
stdoutgrep
direkter mit stdin. Wenn Sie uneingeschränkten Zugriff auf einen Prozess wünschen, den Sie nicht auf diese Weise steuern, müssen Sie sich etwas ansehen/proc
oder Code schreiben, um die Ausgabe zu filtern, indem Sie sich irgendwie in den Kernel einhängen. Es mag andere Lösungen geben, aber sie sind wahrscheinlich alle so gefährlich wie die anderen :-)/dev/stdin
ein Symlink zu/proc/self/fd/0
- dem ersten Dateideskriptor ist, den das aktuell ausgeführte Programm geöffnet hat. Was also darauf hinweist,/dev/stdin
ändert sich von Programm zu Programm, da/proc/self/
immer auf das aktuell laufende Programm verwiesen wird . (Welches Programm auch immer denopen
Aufruf ausführt .)/dev/stdin
Und Freunde wurden dorthin gebracht, um Setuid-Shell-Skripte sicherer zu machen und den Dateinamen/dev/stdin
an Programme zu übergeben, die nur mit Dateien arbeiten, aber interaktiver steuern möchten. (Eines Tages wird dies ein nützlicher Trick für Sie sein. :)Es wäre richtiger zu sagen , dass
stdin
,stdout
undstderr
ist als Dateien eher „I / O - Streams“. Wie Sie bemerkt haben, befinden sich diese Entitäten nicht im Dateisystem. Die Unix-Philosophie in Bezug auf E / A lautet jedoch "Alles ist eine Datei". In der Praxis das wirklich bedeutet , dass Sie die gleichen Bibliotheksfunktionen und Schnittstellen verwenden können (printf
,scanf
,read
,write
,select
, etc.) , ohne sich Gedanken darüber , ob die I / O - Stream mit einer Tastatur verbunden ist, eine Plattendatei, eine Steckdose, ein Rohr, oder eine andere E / A-Abstraktion.Die meisten Programme müssen Eingang, Schreibausgang lesen, und Protokollfehler, so
stdin
,stdout
undstderr
sind für Sie vordefiniert, als Programmierkomfort. Dies ist nur eine Konvention und wird vom Betriebssystem nicht erzwungen.quelle
Als Ergänzung zu den obigen Antworten finden Sie hier eine Zusammenfassung der Weiterleitungen:
EDIT: Diese Grafik ist nicht ganz korrekt, aber ich bin nicht sicher, warum ...
Die Grafik sagt 2> & 1 hat jedoch den gleichen Effekt wie &>
quelle
Ich fürchte, Ihr Verständnis ist völlig rückständig. :) :)
Denken Sie aus der Sicht des Programms an "Standard In", "Standard Out" und "Standard Error" , nicht aus Sicht des Kernels.
Wenn ein Programm eine Ausgabe drucken muss, druckt es normalerweise nach "Standardausgang". Ein Programm druckt normalerweise die Ausgabe nach Standardausgabe mit
printf
, wobei NUR nach Standardausgabe gedruckt wird.Wenn ein Programm Fehlerinformationen drucken muss (nicht unbedingt Ausnahmen, dies ist ein Programmiersprachenkonstrukt, das auf einer viel höheren Ebene auferlegt wird), wird es normalerweise als "Standardfehler" gedruckt. Dies geschieht normalerweise mit
fprintf
, wodurch ein Dateistream akzeptiert wird, der beim Drucken verwendet wird. Der Dateistream kann eine beliebige Datei sein, die zum Schreiben geöffnet wurde: Standardausgabe, Standardfehler oder eine andere Datei, die mitfopen
oder geöffnet wurdefdopen
."Standard in" wird verwendet, wenn die Datei Eingaben mit
fread
oderfgets
oder lesen mussgetchar
.Jede dieser Dateien kann wie folgt einfach von der Shell umgeleitet werden :
Oder die ganze Enchilada:
Es gibt zwei wichtige Einschränkungen: Erstens sind "Standard in", "Standard out" und "Standardfehler" nur eine Konvention. Sie sind eine sehr starke Konvention, aber es ist alles nur eine Vereinbarung, dass es sehr schön ist, Programme wie dieses ausführen zu können:
grep echo /etc/services | awk '{print $2;}' | sort
und die Standardausgaben jedes Programms mit der Standardeingabe des nächsten Programms in der Pipeline zu verknüpfen.Zweitens habe ich die Standard-ISO-C-Funktionen für die Arbeit mit Dateistreams (
FILE *
Objekten) angegeben. Auf Kernelebene sind dies alle Dateideskriptoren (int
Verweise auf die Dateitabelle) und viele Operationen auf niedrigerer Ebene wieread
undwrite
, die dies nicht tun Machen Sie die glückliche Pufferung der ISO C-Funktionen. Ich dachte, es einfach zu halten und die einfacheren Funktionen zu verwenden, aber ich dachte trotzdem, Sie sollten die Alternativen kennen. :) :)quelle
stdin
Liest Eingaben über die Konsole (z. B. Tastatureingabe). Wird in C mit scanf verwendet
stdout
Erzeugt eine Ausgabe an die Konsole. Wird in C mit printf verwendet
stderr
Erzeugt eine 'Fehler'-Ausgabe an die Konsole. Wird in C mit fprintf verwendet
Umleitung
Die Quelle für stdin kann umgeleitet werden. Anstatt von der Tastatureingabe zu stammen, kann es beispielsweise aus einer Datei (
echo < file.txt
) oder einem anderen Programm (ps | grep <userid>
) stammen.Die Ziele für stdout, stderr können ebenfalls umgeleitet werden. Zum Beispiel kann stdout in eine Datei umgeleitet werden:
ls . > ls-output.txt
In diesem Fall wird die Ausgabe in die Datei geschriebenls-output.txt
. Stderr kann mit umgeleitet werden2>
.quelle
Ich denke, Leute, die sagen,
stderr
dass sie nur für Fehlermeldungen verwendet werden sollten, sind irreführend.Es sollte auch für informative Nachrichten verwendet werden, die für den Benutzer bestimmt sind, der den Befehl ausführt, und nicht für potenzielle nachgeschaltete Verbraucher der Daten (dh wenn Sie eine Shell-Pipe ausführen, die mehrere Befehle verkettet, möchten Sie keine informativen Nachrichten wie "Abrufen von Element 30 von" 42424 "wird angezeigt,
stdout
da sie den Verbraucher verwirren. Möglicherweise möchten Sie jedoch, dass der Benutzer sie sieht.Siehe dies für historische Gründe:
quelle
Die Verwendung von ps -aux zeigt aktuelle Prozesse an, die alle in / proc / as / proc / (pid) / aufgeführt sind. Durch Aufrufen von cat / proc / (pid) / fd / 0 wird alles gedruckt, was in der Standardausgabe von gefunden wird diesen Prozess denke ich. Also vielleicht,
/ proc / (pid) / fd / 0 - Standardausgabedatei
/ proc / (pid) / fd / 1 - Standardeingabedatei
/ proc / (pid) / fd / 2 - Standardfehlerdatei
beispielsweise
Aber nur für / bin / bash funktionierte dies gut. Andere Prozesse hatten im Allgemeinen nichts in 0, aber viele hatten Fehler in 2 geschrieben
quelle
Informationen zu diesen Dateien finden Sie in den Manpages. Führen Sie den Befehl auf Ihrem Terminal aus.
Für eine einfache Antwort ist jede Datei für:
Standard für einen Stream aus
stdin für eine Stream-Eingabe
stderr zum Drucken von Fehlern oder Protokollmeldungen.
Jedes Unix-Programm hat jeden dieser Streams.
quelle
stderr führt keine E / A-Cache-Pufferung durch. Wenn unsere Anwendung wichtige Nachrichteninformationen (einige Fehler, Ausnahmen) zur Konsole oder zur Datei drucken muss, verwenden Sie diese, wenn Sie stdout zum Drucken allgemeiner Protokollinformationen verwenden, da die E / A-Cache-Pufferung verwendet wird, besteht die Möglichkeit, dass Vor dem Schreiben unserer Nachrichten in die Dateianwendung wird möglicherweise geschlossen, wodurch das Debuggen komplex wird
quelle
Eine Datei mit zugehöriger Pufferung wird als Stream bezeichnet und als Zeiger auf einen definierten Typ FILE deklariert. Die Funktion fopen () erstellt bestimmte beschreibende Daten für einen Stream und gibt einen Zeiger zurück, um den Stream in allen weiteren Transaktionen zu bestimmen. Normalerweise gibt es drei offene Streams mit konstanten Zeigern, die im Header deklariert und den geöffneten Standarddateien zugeordnet sind. Beim Programmstart sind drei Streams vordefiniert und müssen nicht explizit geöffnet werden: Standardeingabe (zum Lesen herkömmlicher Eingaben), Standardausgabe (zum Schreiben herkömmlicher Ausgaben) und Standardfehler (zum Schreiben diagnostischer Ausgaben). Beim Öffnen ist der Standardfehlerstrom nicht vollständig gepuffert. Die Standardeingabe- und Standardausgabestreams werden genau dann vollständig gepuffert, wenn festgestellt werden kann, dass sich der Stream nicht auf ein interaktives Gerät bezieht
https://www.mkssoftware.com/docs/man5/stdio.5.asp
quelle