Dans
./binary < file
binary
'stdin' est le fichier ouvert en mode lecture seule. Notez que bash
cela ne lit pas le fichier du tout, il l’ouvre simplement pour le lire sur le descripteur de fichier 0 (stdin) du processus binary
dans lequel il s’exécute .
Dans:
./binary << EOF
test
EOF
En fonction du shell, binary
le stdin sera soit un fichier temporaire supprimé (AT & T ksh, zsh, bash ...) qui contient ce qui test\n
est mis ici par le shell ou l'extrémité de lecture d'un tuyau ( dash
, yash
; et le shell écrit test\n
en parallèle à l'autre bout du tuyau). Dans votre cas, si vous utilisez bash
, ce sera un fichier temporaire.
Dans:
cat file | ./binary
Selon le shell, binary
le stdin sera soit l'extrémité de lecture d'un tuyau, soit l'une des extrémités d'une paire de sockets dont le sens d'écriture a été arrêté (ksh93) et cat
écrit le contenu de file
l'autre extrémité.
Lorsque stdin est un fichier normal (temporaire ou non), il est utilisable. binary
peut aller au début ou à la fin, rembobiner, etc. Il peut également ioctl()s
créer une carte , en faire comme FIEMAP / FIBMAP (si vous utilisez <>
plutôt que de <
, il pourrait tronquer / perforer des trous, etc.).
Les pipes et les paires de sockets, quant à eux, sont un moyen de communication inter-processus, il n’ya pas grand binary
chose à faire à côté read
des données (bien qu’il existe aussi des opérations telles que des ioctl()
s spécifiques à un pipe que cela pourrait faire sur eux et non sur des fichiers normaux) .
La plupart du temps, il est la capacité manquante à seek
qui provoque des applications à l' échec / se plaignent lorsque l'on travaille avec des tuyaux, mais il pourrait être l' un des autres appels système qui sont valides sur des fichiers normaux mais pas sur les différents types de fichiers (comme mmap()
, ftruncate()
, fallocate()
) . Sous Linux, il existe également une grande différence de comportement lorsque vous ouvrez /dev/stdin
lorsque le fd 0 est sur un canal ou sur un fichier normal.
Il y a beaucoup de commandes là - bas qui ne peut traiter que adressable fichiers, mais quand c'est le cas, qui est généralement pas pour les fichiers ouverts sur leur stdin.
$ 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
doit lire l'index stocké à la fin du fichier, puis chercher dans le fichier pour lire les membres de l'archive. Mais ici, le fichier (normal dans le premier cas, pipe dans le second) est donné comme argument de chemin unzip
et l' unzip
ouvre lui-même (généralement sur fd autre que 0) au lieu d'hériter d'un fd déjà ouvert par le parent. Il ne lit pas les fichiers zip à partir de son stdin. stdin est principalement utilisé pour l'interaction utilisateur.
Si vous l'exécutez binary
sans redirection à l'invite d'un shell interactif s'exécutant dans un émulateur de terminal, alors binary
stdin sera hérité de son parent le shell, qui l'aura lui-même hérité de son parent l'émulateur de terminal et sera un pty périphérique ouvert en mode lecture + écriture (quelque chose comme /dev/pts/n
).
Ces appareils ne sont pas recherchés non plus. Donc, si cela binary
fonctionne correctement lors de la saisie du terminal, le problème n’est peut-être pas lié à la recherche.
Si ce numéro 14 est censé être un errno (un code d'erreur défini par des appels système défaillants), sur la plupart des systèmes, il s'agirait de EFAULT
( adresse incorrecte ). L' read()
appel système échouerait avec cette erreur s'il était invité à lire dans une adresse mémoire inscriptible. Cela serait indépendant du fait que le fd lise les données des points dans un pipe ou un fichier normal et indiquerait généralement un bogue 1 .
binary
détermine éventuellement le type de fichier ouvert sur son stdin (avec fstat()
) et se heurte à un bogue alors qu'il ne s'agit ni d'un fichier normal ni d'un périphérique tty.
Difficile à dire sans en savoir plus sur l'application. L'exécuter sous strace
(ou truss
/ tusc
équivalent sur votre système) pourrait nous aider à voir quel est l'appel système, s'il y en a un qui échoue ici.
1 Le scénario envisagé par Matthew Ife dans le commentaire de votre question semble fort plausible ici. En le citant:
Je soupçonne qu’il cherche en fin de fichier à obtenir une taille de mémoire tampon pour la lecture des données, gérant mal le fait que la recherche ne fonctionne pas et essayant d’allouer une taille négative (ne traitant pas un mauvais malloc). Passer le tampon pour lire quelles erreurs étant donné que le tampon n'est pas valide.