Im
./binary < file
binary
's stdin ist die Datei, die im schreibgeschützten Modus geöffnet ist. Beachten Sie, dass bash
die Datei überhaupt nicht gelesen wird, sondern nur zum Lesen im Dateideskriptor 0 (stdin) des Prozesses geöffnet wird, binary
in dem sie ausgeführt wird .
Im:
./binary << EOF
test
EOF
Abhängig von der Shell ist binary
stdin entweder eine gelöschte temporäre Datei (AT & T ksh, zsh, bash ...), die test\n
das von der Shell gesetzte Ende einer Pipe enthält , oder das Leseende einer Pipe ( dash
, yash
; und die Shell schreibt test\n
parallel am anderen Ende der Leitung). In Ihrem Fall bash
wäre dies eine temporäre Datei.
Im:
cat file | ./binary
Abhängig von der Shell ist binary
stdin entweder das Leseende einer Pipe oder ein Ende eines Socket-Paares, bei dem die Schreibrichtung heruntergefahren wurde (ksh93) und cat
der Inhalt von file
am anderen Ende geschrieben wird.
Wenn stdin eine reguläre Datei ist (temporär oder nicht), kann danach gesucht werden. binary
kann an den Anfang oder das Ende gehen, zurückspulen usw. Es kann es auch mappen, etwas ioctl()s
wie FIEMAP / FIBMAP tun (wenn es <>
anstelle von verwendet wird <
, könnte es Löcher darin abschneiden / lochen usw.).
Pipes und Socket-Paare hingegen sind ein Kommunikationsmittel zwischen Prozessen. binary
Neben read
den Daten gibt es nicht viel zu tun (obwohl es auch einige Operationen gibt, wie z. B. einige Pipe-spezifische Operationen ioctl()
, die für sie und nicht für reguläre Dateien ausgeführt werden könnten). .
Die meisten der Zeit, es ist die fehlende Möglichkeit, seek
die Anwendungen scheitern / beschweren , wenn die Arbeit mit Rohren verursacht, aber es könnte eine der anderen Systemaufrufe, die auf reguläre Dateien gültig sind , aber nicht auf verschiedene Arten von Dateien (wie mmap()
, ftruncate()
, fallocate()
) . Unter Linux gibt es auch einen großen Unterschied im Verhalten, wenn Sie öffnen, /dev/stdin
während sich der fd 0 in einer Pipe oder in einer regulären Datei befindet.
Es gibt viele Befehle, die sich nur mit durchsuchbaren Dateien befassen können, aber wenn dies der Fall ist, gilt dies im Allgemeinen nicht für die Dateien, die im Standardverzeichnis geöffnet sind.
$ unzip -l file.zip
Archive: file.zip
Length Date Time Name
--------- ---------- ----- ----
11 2016-12-21 14:43 file
--------- -------
11 1 file
$ unzip -l <(cat file.zip)
# more or less the same as cat file.zip | unzip -l /dev/stdin
Archive: /proc/self/fd/11
End-of-central-directory signature not found. Either this file is not
a zipfile, or it constitutes one disk of a multi-part archive. In the
latter case the central directory and zipfile comment will be found on
the last disk(s) of this archive.
unzip: cannot find zipfile directory in one of /proc/self/fd/11 or
/proc/self/fd/11.zip, and cannot find /proc/self/fd/11.ZIP, period.
unzip
muss den Index lesen, der am Ende der Datei gespeichert ist, und dann in der Datei nach den Archivmitgliedern suchen. Aber hier wird die Datei (regulär im ersten Fall, Pipe im zweiten Fall) als Pfadargument für angegeben unzip
und unzip
öffnet sie selbst (normalerweise auf fd ungleich 0), anstatt ein fd zu erben, das bereits vom übergeordneten Element geöffnet wurde. Es liest keine zip-Dateien von seinem Standard. stdin wird hauptsächlich für die Benutzerinteraktion verwendet.
Wenn Sie binary
Ihre eigene Shell ohne Umleitung ausführen, binary
während eine interaktive Shell in einem Terminalemulator ausgeführt wird, wird die Standard-ID von der übergeordneten Shell geerbt, die sie selbst von der übergeordneten Shell, dem Terminalemulator, geerbt hat pty-Gerät im Lese- und Schreibmodus öffnen (so etwas wie /dev/pts/n
).
Diese Geräte sind auch nicht suchbar. binary
Wenn die Eingabe über das Terminal einwandfrei funktioniert, liegt das Problem möglicherweise nicht in der Suche.
Wenn die 14 gemeint ist eine errno sein (einen Fehlercode gesetzt durch Systemaufrufe nicht an ), dann auf den meisten Systemen, wäre die EFAULT
( Bad - Adresse ). Der read()
Systemaufruf schlägt mit diesem Fehler fehl, wenn er zum Einlesen einer nicht beschreibbaren Speicheradresse aufgefordert wird. Das wäre unabhängig davon, ob der fd die Daten von Punkten in eine Pipe oder eine reguläre Datei liest und würde generell einen Bug 1 anzeigen .
binary
Ermittelt möglicherweise den Typ der Datei, die im Standardverzeichnis (mit fstat()
) geöffnet ist, und stößt auf einen Fehler, wenn es sich weder um eine reguläre Datei noch um ein tty-Gerät handelt.
Schwer zu sagen, ohne mehr über die Anwendung zu wissen. Laufen sie unter strace
(oder truss
/ tusc
äquivalent auf Ihrem System) könnte dazu beitragen , uns zu sehen , was der Systemaufruf, wenn überhaupt , die hier versagt.
1 Das von Matthew Ife in einem Kommentar zu Ihrer Frage ins Auge gefasste Szenario klingt hier sehr plausibel. Zitiert ihn:
Ich vermute, es wird versucht, bis zum Ende der Datei eine Puffergröße für das Lesen der Daten zu erhalten, die Tatsache, dass das Suchen nicht funktioniert, schlecht zu handhaben und zu versuchen, eine negative Größe zuzuweisen (kein schlechtes Malloc zu handhaben). Das Übergeben des Puffers, um zu lesen, welche Fehler im Puffer vorliegen, ist ungültig.