2010-04-16 3 views
3

J'ai actuellement une commande Bash en cours d'exécution (via subprocess.Popen de Python) qui lit à partir de stdin, en faisant quelque chose et en produisant stdout. Quelque chose le long des lignes de:Comment rediriger stdin/stdout lorsque j'ai une séquence de commandes dans Bash?

pid = subprocess.Popen(["-c", "cmd1 | cmd2"], 
         stdin = subprocess.PIPE, 
         stdout = subprocess.PIPE, 
         shell =True) 
output_data = pid.communicate("input data\n") 

Maintenant, ce que je veux faire est de changer cela pour exécuter une autre commande dans ce même sous-shell qui changera l'état avant les prochaines commandes exécuter, donc ma ligne de commande shell va maintenant (conceptuel) être:

cmd0; cmd1 | cmd2 

est-il possible d'avoir l'entrée envoyée à cmd1 au lieu de cmd0 dans ce scénario? Je suppose que la sortie inclura la sortie de cmd0 (qui sera vide) suivie par la sortie cmd2.

cmd0 ne devrait pas réellement lire quelque chose de stdin, cela fait-il une différence dans cette situation?

Je sais que c'est probablement juste une manière stupide de faire ceci, j'essaye de corriger en cmd0 sans altérer l'autre code trop significativement. Cela dit, je suis ouvert aux suggestions s'il y a une façon beaucoup plus propre d'aborder cela.

+0

Il est difficile de comprendre ce que vous demandez. Donnez peut-être un exemple précis ou, mieux encore, décrivez ce que vous essayez de faire. – wallyk

Répondre

4

exécuter CMD0 et cmd1 dans un sous-shell et rediriger /dev/null comme stdin pour CMD0:

(cmd0 </dev/null; cmd1) | cmd2 
+0

+1: bien que l'OP ait dit que cmd0 ne touchera pas stdin, bon pour être sûr! – Cascabel

1

Je ne pense pas que vous devriez faire quelque chose de spécial. Si cmd0 ne touche pas stdin, il sera intact pour cmd1. Essayez vous-même:

ls | (echo "foo"; sed 's/^/input: /') 

(En utilisant ls comme une commande arbitraire pour produire quelques lignes d'entrée pour le pipeline)

et le tuyau supplémentaire pour cmd2 n'affecte pas non plus l'entrée, bien sûr.

+0

Ok, ça a l'air bien et c'est ce que j'avais besoin de savoir. Je vais essayer quand je peux. – Tom

0

Ok, je pense que je peux être en mesure de reproduire le fichier stdin descripteur à un temporaire, fermez-le, exécutez cmd0, puis la restaurer avant d'exécuter cmd1:

exec 0>&3; exec 0<&-; cmd0 ; exec 3>&0 ; cmd1 | cmd2 

Vous ne savez pas s'il est possible de rediriger stdin de cette manière, et vous ne pouvez pas le tester pour le moment.

http://tldp.org/LDP/abs/html/io-redirection.html

http://tldp.org/LDP/abs/html/x17601.html

+0

ok, ce n'est probablement pas nécessaire (même si ça allait marcher) étant donné les autres réponses que les gens ont données. – Tom

Questions connexes