Dans
./binary < file
binary'stdin' est le fichier ouvert en mode lecture seule. Notez que bashcela ne lit pas le fichier du tout, il l’ouvre simplement pour le lire sur le descripteur de fichier 0 (stdin) du processus binarydans lequel il s’exécute .
Dans:
./binary << EOF
test
EOF
En fonction du shell, binaryle stdin sera soit un fichier temporaire supprimé (AT & T ksh, zsh, bash ...) qui contient ce qui test\nest mis ici par le shell ou l'extrémité de lecture d'un tuyau ( dash, yash; et le shell écrit test\nen 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, binaryle 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 filel'autre extrémité.
Lorsque stdin est un fichier normal (temporaire ou non), il est utilisable. binarypeut aller au début ou à la fin, rembobiner, etc. Il peut également ioctl()scré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 binarychose à faire à côté readdes 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 à seekqui 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/stdinlorsque 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.
unzipdoit 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 unzipet l' unzipouvre 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 binarysans redirection à l'invite d'un shell interactif s'exécutant dans un émulateur de terminal, alors binarystdin 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 binaryfonctionne 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 .
binarydé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.