7
votes

STDIN se comporte différemment lorsqu'il est tiré et quand redirigé

J'essaie de transmettre des informations dans un programme qui n'accepte pas l'entrée de STDIN. Pour ce faire, j'utilise le / dev / stdin comme un argument puis essayant de faire du tuyau dans mon entrée. J'ai remarqué que si je le fais avec un personnage de tuyau:

_llseek(3, 0, [0], SEEK_CUR)            = 0 


4 commentaires

Consultez les informations ici: Stackoverflow.com/Questtions/1312922/...


C'est intéressant, mais cela ne semble pas faire un tel chèque. Et peu importe que la production d'IsatTy () ne devrait-elle pas être la même dans les deux cas d'entrée mentionnés ici? Cela contraste avec le poste lié qui n'a aucune entrée redirigée.


Selon la deuxième réponse | Retourne oui pour isatty alors que Stackoverflow.com/a/7601564/2269047


Cela pourrait également être intéressant: Stackoverflow .com / questions / 1563882 / ...


3 Réponses :


0
votes

de regarder ces informations sur MC-Annotate http: // bioinfo .Cipf.es / ddufour / doku.php? id = mc-annotate La raison pour laquelle le tuyau ne fonctionne pas est parce que MC-Annotate ne reconnaît pas la sortie CAT à partir du fichier en tant que de type .pbd

Les chaînes de tuyaux commandent ensemble la sortie du premier est utilisée comme entrée à la suivante.

Le '<' (<'(' moins que ', «flèche gauche», «support d'angle gauche») entrait le fichier dans la commande.

http://tldp.org/ldp/abs/html/ io-redirection.html # ioredrectionRef2


5 commentaires

Pourquoi cela seraient-ils le cas cependant? Le fichier PDB est juste un fichier texte. Si vous effectuez le suivant cat.pdb> out1.pdb; DIFF OUT.PDB OUT1.PDB , il n'y a pas de différence, ce qui me conduit à croire que la sortie de la commande chat est identique au fichier d'origine.


Parce que la sortie de CAT n'est pas un fichier PDB. En regardant la documentation pour MC-Annotate, il existe une option -b pour lire le fichier binaire plutôt que pdb. Je devinerais que la logique du type de fichier est interne à MC-Annotate.


Je pense que vous avez probablement raison depuis que je ne vois pas un comportement similaire avec d'autres programmes. Cependant, je ne peux toujours pas envelopper ma tête autour de la raison pour laquelle le fichier et l'entrée de canalisation doivent être traités différemment quand ils sont exactement les mêmes en termes de ce qu'ils contiennent.


Si la commande vérifie que le fichier dispose d'une extension PDB avant de le traiter, l'entrée de la canalisation échouerait car elle n'aura pas l'extension.


Ce n'est pas le cas. Cela fonctionne lorsque vous utilisez une extension de fichier différente. Bien que cela essaie peut-être de rechercher l'entrée et l'échec de la fin du terminal.



1
votes

Le problème réside dans l'ordre dans lequel les fichiers sont ouverts à la lecture.

/ dev / stdin code> n'est pas un fichier réel; C'est un lien symbolique du fichier que le processus actuel utilise en entrée standard. Dans une coque typique, elle est liée au terminal et héritée par tout processus lancé par la coquille. N'oubliez pas que mc-annotate annotate ne sera lu que dans le fichier fourni sous forme d'argument. P>

dans l'exemple de tuyau, / dev / stdin code> est un Symlink au fichier que MC-Annotate code> hérite en entrée standard: le terminal. Il ouvre probablement ce fichier sur un nouveau descripteur (disons 3, mais cela pourrait être une valeur supérieure à 2). Le tuyau relie la sortie de cat code> à entrée standard MC-ANNOTATE (descripteur de fichier 0), que mc-annotate code> continue d'ignorer en faveur de Le fichier qu'il a ouvert directement. p>

Dans l'exemple de redirection, le shell connecte faches / structures / 168d.pdb code> directement sur le descripteur de fichier 0 avant em> MC-Annotate code> est exécuté. Lorsque mc-annotate code> démarre, il essaie à nouveau d'ouvrir / dev / stdin code>, que ce temps pointe vers Fess / Structures / 168D.PDB CODE> Au lieu du terminal. p>

donc la réponse réside dans quel fichier / dev / stdin code> est un lien vers dans le processus qui exécute mc-annotate code>; Les redirections de shell sont configurées avant le début du processus; Pipelines après em> le processus commence. P>

Est-ce que cela fonctionne? P>

cat fess/structures/168d.pdb | { MC-Annotate /dev/stdin; }


5 commentaires

Wow! Grande description. Toute façon de le tromper à ne pas ouvrir un nouveau descripteur de fichier lors de la réception d'une entrée de tuyauterie?


Voir ma mise à jour. mc-annotate va toujours ouvrir un nouveau descripteur de fichier; Je ne pense pas que le programme fait une sorte de détection interne: cela n'ouvre que le fichier présenté sur la ligne de commande. Cependant, ma mise à jour montre un moyen d'exécuter mc-annotate dans un environnement où il hérite d'autre chose que le terminal comme entrée standard.


Ce n'est pas correct. La coquille évalue les pipelines avant Il installe des redirections. C'est pourquoi (echo stdout; echo stdeur 1> & 2) 2> & 1 | grep stdout imprime uniquement "stdout". Si les redirections ont été configurées d'abord, comme suggéré ici, cette commande imprimerait "stdout" et "stardr" parce que l'appel à DUP2 () de la redirection se produirait avant le DUP2 () pour le réglage de la conduite et Puis définissez 1 pour pointer sur 0 de grep (vous voyez donc les deux). Mais en réalité, le DUP2 () pour le tuyau arrive en premier - 1 est défini sur Point à Grep, puis 2 est réglé sur Point à 1 (qui va au grep).


@Christopherneylan je pense que la différence ici est la complication ajoutée de l'ouverture / dev / stdin explicitement, qui n'est pas effectuée qu'après toutes les choses spécifiques à la coque, et après MC-Annotate est exécuté.


Mais c'est un point différent entièrement, et cela n'ajoute même pas de complexité - / dev / stdin n'est qu'un lien vers / proc / auto / fd / 0, donc MC-Annotate fait simplement une ouverture () sur / proc / $$ / FD / 0, qui aura déjà été mis en place par la coquille (quelle que soit la redirection ou la pipeline). Mon point ci-dessus était que la coquille fait son DUP2 () pour les pipes avant il gère les redirections.



2
votes

Il ne devrait y avoir aucune différence fonctionnelle entre ces deux commandes. En effet, je ne peux pas recréer ce que vous voyez: xxx

en cours d'exécution de trois manières: xxx

Première note que / dev / stdin est: xxx

C'est toujours un symbole symbolique de / proc / profonc / fd / 0 . / proc / auto est lui-même un lien spécial vers le répertoire sous / proc pour le processus en cours. Donc, / dev / stdin pointera toujours sur FD 0 du processus en cours. Donc, lorsque vous exécutez mc-annotate (ou, dans mes exemples, test.pl ), le fichier / dev / stdin se résoudre à < Code> / proc / $ pid / fd / 0 , pour quel que soit l'ID de processus de MC-Annotate est. Il s'agit simplement d'un résultat de la façon dont le symbole symbolique pour / dev / stdin fonctionne.

afin que vous puissiez voir ci-dessus dans mon exemple, lorsque vous utilisez un tuyau ( | ), / proc / fd / 0 pointera sur l'extrémité de lecture du tuyau à partir de CAT configuré par la coque. Lorsque vous utilisez une redirection ( << / code>), / proc / fd / 0 pointera directement sur le fichier d'entrée, comme configuré par la coque.

Pourquoi vous voyez ce comportement étrange - je suppose que mc-annotate fait des chèques sur le fichier de fichiers avant de l'ouvrir et que vous voyez que / dev / stdin pointe à un tuyau nommé au lieu d'un fichier ordinaire, et est perforée. Vous pouvez confirmer cela en lisant le code source pour mc-annotate ou à l'aide de la commande strace pour regarder ce qui se passe à l'intérieur.

Notez que les deux de ces méthodes sont un peu ronds à Bash. Le moyen accepté d'obtenir la sortie d'un processus dans un programme qui ouvrira uniquement un nom de fichier est d'utiliser substitution de processus : xxx

<(...) construction renvoie un descripteur de fichier à la lecture de la lecture Un tuyau qui vient de tout ce que ... est: xxx


0 commentaires