Warum benötigen manche Befehle keine Eingabeumleitung?

365
angelcool.net

Zum Beispiel echo :

[aesteban@localhost ~]$ cat tmp.txt  Angel [aesteban@localhost ~]$ echo < tmp.txt  [aesteban@localhost ~]$ 

Wie Sie sehen, ist die Ausgabe nur eine leere Zeile. Nach meinen Angaben können einige Befehle Eingaben umleiten, z. B. Mail :

[aesteban@localhost ~]$ mail barney@example.com < tmp.txt 

Gilt die Umleitung von Eingaben nur für interaktive Befehle (die auf Eingaben warten können)? Wie können Sie feststellen, ob ein Befehl interaktiv ist (abgesehen von den Versuchen)?

4

3 Antworten auf die Frage

3
Edward

Warum benötigen manche Befehle keine Eingabeumleitung?

Die kurze Antwort: weil sie nicht programmiert waren.

Für ein Programm, aus dem gelesen werden soll stdin(dh der Stream, mit dem die Shell eine Verbindung mit der danach angegebenen Datei herstellt <), ist nicht automatisch. Es muss vom Programmierer codiert werden. Das Lesen von Dateien, die in der Befehlszeile angegeben sind, erfolgt ebenfalls nicht automatisch. Das heißt, der Inhalt dieser Dateien, egal ob durch Umleitung oder durch Namen angegeben, erscheint nicht magisch in den Programmvariablen ohne zusätzliche Codierung.

Wenn ein Programm nie zum Lesen aus einem Stream codiert wurde, ist es unerheblich, ob Sie eine Umleitung angeben - es wird einfach nicht gelesen. Nach seiner POSIX-Spezifikation ( http://pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html ) muss echonicht gelesen werden, sondern stdinnur die Befehlszeilenargumente (und einige Umgebungsvariablen). Für andere Programme können Sie den Quellcode und die Dokumentation lesen oder einfach wie gesagt ausprobieren :-)

Um Ihre letzte Frage zu beantworten: Sie können nicht wirklich sagen, dass ein Befehl interaktiv ist. Sie können bestimmen, ob der Eingabestrom, von dem er liest, mit einem Terminal verbunden ist (im Gegensatz zu einer einfachen Datei). Es gibt Beispiele in vielen Sprachen unter http://rosettacode.org/wiki/Check_input_device_is_a_terminal . Sie könnten sich ein Mailing-Programm vorstellen, das diese Funktion verwendet, um zu bestimmen, ob es interaktiv verwendet wird (Tastaturbefehle zum Lesen von E-Mails akzeptieren) oder nicht interaktiv (z. B. zum Lesen einer E-Mail-Nachricht aus einer Datei). Ich bin nicht sicher, wie mailes geht. (Beachten Sie, dass mailsich das Verhalten bei Aufruf mit oder ohne Befehlszeilenargument anders verhält!)

1
Scott

Die meisten Befehle, die den Inhalt einer Datei (oder von Dateien) lesen, deren Name in der Befehlszeile angegeben ist, werden aus der Standardeingabe gelesen, wenn in der Befehlszeile keine Dateien angegeben sind. Einige lesen auch aus der Standardeingabe, wenn - in der Befehlszeile ein Dateiname angegeben ist. z.B,

katze datei 1  -  datei 2

liest aus, dann Standardeingabe und dann . Wenn ein Befehl jedoch normalerweise nicht den Inhalt der Datei (en) liest, deren Name (n) in der Befehlszeile angegeben sind, wird er wahrscheinlich auch nichts mit der Standardeingabe tun. Liest niemals aus Dateien.file1file2echo

Natürlich gibt es verschiedene Ausnahmen:

  • Der trBefehl liest immer aus der Standardeingabe und akzeptiert keine Dateinamen in der Befehlszeile.
  • Wenn bcmit Argumenten von Dateinamen aufgerufen wird, werden diese gelesen und auch die Standardeingabe gelesen, es sei denn, eine der Dateien enthält den Befehl haltoder quit.
  • Compiler (z. B. der C-Compiler, der ccoder genannt werden kann gcc) erfordern (oder bevorzugen) Dateinamen in der Befehlszeile.  ccschlägt fehl, wenn ohne Dateinamen in der Befehlszeile aufgerufen wird. cc -liest die Standardeingabe nur, wenn bestimmte Optionen angegeben sind.
  • Es ist nicht sinnvoll, cmpoder diff mit weniger als zwei Eingabequellen aufzurufen . Sie schlagen fehl, wenn sie ohne Dateinamen in der Befehlszeile aufgerufen werden. Beide respektieren die Konvention, dass ein Argument -die Standardeingabe bezeichnet.  ist äquivalent zu ; dh es wird mit der Standardeingabe verglichen .  schlägt fehl, wenn mit einem Dateinamenargument aufgerufen wird; Sie müssten sagen .cmp file1cmp file1 -file1diffdiff file1 -
  • Und während ddwird ein akzeptieren i nput f ile auf der Kommandozeile angegeben, wenn es wie vorgestellt, zum Beispiel,if=filename

    dd if=my_iso_file of=/dev/sda1 

    ( ofIst o utput f ile), und es wird von der Standardeingabe lesen, wenn Sie nicht angeben if; z.B,

    dd of=/dev/sda1 < my_iso_file 

    Es akzeptiert keine Befehlszeilenargumente, bei denen es sich nicht um Dateinamen handelt, die nicht verziert sind (also beispielsweise funktionieren dd my_iso_file > /dev/sda1und nicht funktionieren). (Außerdem werden im Gegensatz zu den meisten Befehlen, die aus Dateien lesen, nicht mehr als eine Eingabedatei von der Befehlszeile aus verarbeitet.)dd my_iso_file of=/dev/sda1dd

(Es gibt wahrscheinlich andere.)

Technisch gesehen können Sie eine Datei nach `dd` umleiten:` dd status = none </ proc / uptime` Steven vor 8 Jahren 0
0
Steven

Lesen Sie die Dokumentation.

Der Befehl echo liest nicht aus stdin. Die Eingabeumleitung bewirkt daher nichts. Das Bash-Handbuch besagt:

echo: Gibt die durch Leerzeichen getrennten Argumente aus, gefolgt von einer neuen Zeile.

Manpage für cat:

cat - verkettet Dateien und druckt auf der Standardausgabe.