Ihre Frage hängt eng damit zusammen, wie die von Ihnen verwendete Shell Benutzereingaben in der Befehlszeile analysiert.
Wenn das erste Wort in der Befehlszeile ein Programm ist, das sich in einem speziellen Ordner befindet (meistens definiert durch PATH
) und keine Sonderzeichen mehr angegeben werden (abhängig von der verwendeten Shell), werden alle nachfolgenden Wörter, die durch Leerzeichen oder Tabulatoren getrennt sind, übergeben das Programm in einer speziellen Form, dh einem Array. Mit jedem Wort als ein Element im Array.
Wie das aufzurufende Programm die Argumente (im Array) interpretiert, hängt davon ab, wie es programmiert ist. Es gibt einige Quasi-Standards, wie die Syntax der Argumente aussehen sollte, aber im Allgemeinen ist der Programmierer völlig frei. Das erste Argument kann also als Name einer Datei interpretiert werden, oder was auch immer der Programmierer zum Zeitpunkt der Erstellung des Programms dachte.
Im Fall , dass Sie das Sonderzeichen hinzuzufügen <
oder >
zu der Befehlszeile, die Shell dosn't append <
und >
noch nachfolgende Worte an das Array , das an das Programm übergeben werden. Mit <
or >
given beginnt die Shell, ausgefallene Dinge zu machen, die vom zugrunde liegenden Kernel unterstützt werden (Keyword Piping ). Um zu verstehen, was los ist, muss man verstehen, was STDIN
und STDOUT
(da es nicht unmittelbar damit zusammenhängt, lasse ich es aus STDERR
).
Alles, was Sie auf Ihrem Terminal sehen (in den meisten Fällen ein Teil Ihrer Anzeige), wird entweder von der Shell oder einem anderen Programm, das Sie zuvor aufgerufen haben, in eine spezielle Datei geschrieben (in Unix ist alles eine Datei ). Diese Datei hat eine spezielle ID und wird aufgerufen STDOUT
. Wenn ein Programm Daten von der Tastatur lesen möchte, fragt es die Tastatur nicht direkt ab (zumindest in den meisten Fällen), sondern liest aus einer speziellen Datei namens STDIN
. Intern ist diese Datei mit Ihrem Standardeingabegerät verbunden, in den meisten Fällen Ihrer Tastatur.
Wenn die Shell eine geparste Befehlszeile liest <
oder >
eingibt, manipuliert sie diese für die Zeit, in der das entsprechende Programm ausgeführt wird, STDIN
oder STDOUT
in einer bestimmten Art. STDIN
und STDOUT
zeigen Sie nicht mehr auf das Terminal oder das Standard-Eingabegerät, sondern auf den nachfolgenden Dateinamen in der Befehlszeile.
Im Falle der beiden Zeilen
cat file_name
cat < file_name
Das beobachtete Verhalten ist identisch, da der entsprechende Entwickler die cat
Daten entweder STDIN
aus der Datei liest oder aus ihr liest, deren Name als erstes Befehlszeilenargument angegeben wird (das ist das erste Element in dem Array, an das die Shell übergibt cat
). Anschließend cat
schreibt den gesamten Inhalt file_name
oder STDIN
zum Terminal , da wir die Schale nicht anweisen zu manipulieren zu STDOUT
. Denken Sie daran, dass Ihre Shell in der zweiten Zeile so manipuliert STDIN
, dass sie nicht mehr auf Ihr Standardeingabegerät, sondern auf eine Datei verweist, die file_name
in Ihrem aktuellen Arbeitsverzeichnis aufgerufen wird .
Im anderen Fall der Leitung
man < file_name
man
soll nichts auslesen, STDIN
wenn es ohne Argument aufgerufen wird, dh ein leeres Array. Also die Leitung
man < file_name
gleich
man
Zum Beispiel man
liest auch etwas aus STDIN
, wenn Sie -l -
an übergeben man
. Mit dieser Option in der Befehlszeile können Sie den Inhalt aller man
Lesevorgänge STDIN
auf Ihrem Terminal anzeigen . So
man -l - < file_name
würde auch funktionieren (aber sei vorsichtig, man
ist nicht nur ein Pager, sondern analysiert auch die Eingabe der Datei und so kann der Dateiinhalt und der angezeigte Inhalt abweichen).
So wie STDIN
, STDOUT
und die Befehlszeilenargumente werden so interpretiert , ist alles an den entsprechenden Entwickler auf.
Ich hoffe meine Antwort konnte die Dinge klären.
man -l - < file_name
vonman
InterpretenSTDIN
als Argumente erwähnt. In meinem System schlägt dies jedoch fehlSTDERR
:man -l - < tee man: invalid option -- l man, version 1.6c
man
( man-db ) ArgumenteSTDIN
mit den angegebenen Argumenten-l
gefolgt von liest-
. Es interpretiert nur Daten vonSTDIN
als Manpage. Ausführlichere Erklärungen zu gültigen Argumenten und deren Interpretation finden Sie auf der Manpage des jeweiligen Programms. In Ihrem Fall konsultierenman man
. Vielleicht gibt es eine ähnliche Option für Ihreman
. Wenn Sie Befehlszeilenargumente für ein bestimmtes Programm lesen möchtenSTDIN
xargs
(wie oben erwähnt), ist dies der richtige Weg.man man
und finde die in meinem Betriebssystem unterstützt es nicht. Wie auch immer, danke für diese Erklärung dieser beiden Konzepte für mich.Sie sind völlig anders. Befehlszeilenargumente werden in einem Array an das Programm übergeben und es kann damit tun, was es will. stdin ist ein Eingabestream, von dem das Programm Daten anfordern muss. Programme, die Dateien verarbeiten, unterstützen häufig beides, müssen dies jedoch manuell tun. Sie überprüfen, ob ein Dateiname als Befehlszeilenargument übergeben wurde, und lesen stattdessen von stdin
Sie scheinen damit zu rechnen
man
, stdin zu lesen, um die Manpage zu finden, die angezeigt werden soll, was ein wirklich merkwürdiges Verhalten wäre. Wann würdest du das jemals benutzen? Die Tatsache, dasscat
sein Standard angezeigt wird, ist ein Artefakt der Tatsache, dass es nichts anderes tut; Ich glaube nicht, dass ein anderes Tool so funktioniert.grep
Kann zum Beispiel einen Dateinamen übernehmen oder lesenstdin
, verarbeitet aber die Daten weiterstdin
, liest keinen Dateinamen ausstdin
und öffnet ihn dannWenn Sie dieses Verhalten wirklich benötigen, können Sie Folgendes verwenden
xargs
, um eine Datei in Befehlszeilenargumente zu konvertieren:Oder binden Sie einfach einen
cat
Anruf in denman
Anruf ein:quelle
man $(<file_name)
.(<>)
in einer Schleife wirdSTDIN
oder Befehlszeilenargumente als Dateinamen ...man < file_name
ist, mir zu helfen, diese zwei Konzepte zu verstehen. Wenn Sie Ihre Erklärung lesen, entscheidet der Befehlsautor über die Implementierung. Also, wenn ich unter Recht, verarbeitet diefind
nimmt Argumente eher STDIN?