8
votes

Comment exécuter le processus dans Python où les données sont écrites dans STDIN?

J'ai un drapeau dans mon script Python qui spécifie si je configure et utilise un processus externe ou non. Ce processus est une commande appelée my_command et prend des données à partir d'une entrée standard. Si je devais courir ceci sur la ligne de commande, ce serait quelque chose comme: xxx

Je veux utiliser un script python pour générer des lignes de données en modifiant Entrée standard et l'alimentation sur MY_COMMAND .

Je fais quelque chose comme ceci: xxx

Toutefois, my_command se comporte comme s'il ne reçoit aucune donnée et quitte avec un état d'erreur. Qu'est-ce que je fais mal?

edit

Disons que mon script Python s'appelle my_pytHon_script . Disons que je passerais normalement my_command un fichier appelé data sur une entrée standard: xxx

mais maintenant je passe C'est à my_python_script à la place: xxx

je veux my_python_script pour configurer de manière conditionnelle un sous-processus qui fonctionne My_Command < / Code> sur le contenu de DATA (qui sont modifiés par my_python_script avant d'être passé sur My_Command ). Cela a-t-il plus de sens?

Si j'utilisais bash comme langage de script, je déciderais de lancer l'une des deux fonctions. On pourrait pipeler des lignes de données sur my_command . L'autre ne serait pas. Peut-il être fait avec python?


4 commentaires

Quel type de fichier est my_command ? Est-ce un script shell? Script Python? Vous voudrez peut-être essayer quelque chose comme ['/ bin / bash', 'my_command'] ou quelque chose de similaire pour le script Python.


Vous pouvez écrire my_python_script en tant que filtre UNIX à la place. Ensuite, le script python ne sait rien sur my_command et lit simplement à partir de STDIN, la modifie en quelque sorte, et s'imprime sur stdout: ` quelque_other_result


Si stdout = tuyau , vous devriez le lire, sinon le processus pourrait bloquer s'il génère suffisamment de sortie.


Un exemple simple de communication à double sens entre un processus primaire et une sous-processus peut être trouvé ici: Stackoverflow.com/a/52841475/1349673 < / a>


3 Réponses :


0
votes

5 commentaires

Je ne comprends pas. J'essaie de transmettre my_command modifié des données à partir du script, ne pas avoir le type d'utilisateur final dans les données manuellement via le terminal. Tout doit être traité dans le script. Cela a-t-il plus de sens?


@Alexreynolds Si vous tapez à la coquille. Comment passeriez-vous dans plusieurs lignes d'entrée comme argument à une commande? Je pense que vous êtes des arguments déroutants (c.-à-d.: La commande arg1 arg2 arg2 ) et stdin (c.-à-d .: (echo arg1; echo arg2; echo arg3) | commande . Vous devez expliquer lequel est-ce que tu veux


Je pense que la confusion est que si vous appelez $ python name_of_script.py résultat Vous ne passez pas l'entrée standard de fichier, vous passez le fichier comme un argument. Vous pouvez obtenir une liste d'arguments à partir de sys.argv .


Si j'utilise $ my_python_script résultat sans tous les Subgrocess Stuff, il gère une entrée standard et une sortie juste bien, donc je ne pense pas que les arguments de fichier soient le problème ici . En fait, si je laissez la redirection, alors le pour la boucle est suspendu, en attente de l'entrée standard. J'essaie simplement de comprendre comment incorporer une instance de processus de sous-processus dans ce script.


@Alexreynolds, cette commande est-elle équivalente à celle que vous avez fournie? Données CAT | my_python_script> résultat . Juste pour nettoyer la confusion.



9
votes

Après avoir écrit à la STDIN, vous devez le fermer:

for ...
    process.stdin.write(modified_line)

process.stdin.close()
process.wait()


2 commentaires

Cela jette une exception ValueError sur la seconde passe via le pour boucle: ValueError: Opération d'E / S sur fichier fermé . La commande my_command traite plusieurs lignes (en réalité, elle imite une application spécifique d'unix trier ) afin que la poignée STDIN doit rester ouverte, je pense.


Pouvez-vous fermer après la boucle? Ma faute.



3
votes

En plus de processus.stdin.close () comme mentionné par @haivi, avez-vous fait processus.wait () pour attendre la fin de la commande avant d'avoir le résultat?


1 commentaires

J'ai oublié processus.wait () . Bonne prise.