2016-06-13 14 views
2

Nehmen wir an, es gibt ein Programm namens 'ABC', das 4 ganze Zahlen von stdin liest und etwas damit macht.subprocess.Popen - stdin erneut umleiten

Vor kurzem leanred ich, dass wir Pipeline verwenden können, die Eingänge zu ABC zu füttern, wie folgt vor:

# send.py 
import subprocess 

p = subprocess.Popen(['ABC'], stdin = subprocess.PIPE) 
print >>p.stdin, '1 2 3 4' 

Meine Frage ist: Können wir stdin wieder nach dem Aufruf von subprocess.Popen umleiten ?? Beispiel:

# send.py 
import subprocess 

p = subprocess.Popen(['ABC'], stdin = subprocess.PIPE) 
print >>p.stdin, '1 2 3' 

(Redirect p.stdin to terminal's stdin) 

, so dass wir die vierte Ganzzahl in ABC eingeben können, indem Sie das Terminal eingeben.

+1

Sie wollen 'send.py' von stdin lesen und dann in' ABC's stdin schreiben? Ja, absolut kannst du das tun. Und es heißt in diesem Fall nicht "Umleitung" - jedes Programm hat seine eigene Standardeingabe. Verwenden Sie 'input()' oder 'sys.stdin.read()'. –

Antwort

1

Die Umleitung erfolgt, bevor ABC z.B. ausgeführt wird, (auf Unix) nach dem fork() aber bevor execv() (look at dup2() calls). Es ist zu spät, den gleichen OS-Level-Mechanismus für die Umleitung nach Popen() zu verwenden, aber Sie könnten es manuell emulieren.

Um "redirect p.stdin an Terminals stdin" während der Prozess ausgeführt wird, rufen shutil.copyfileobj(sys.stdin, p.stdin). Es könnte Pufferprobleme geben und der Kindprozess könnte außerhalb seiner Standardeingabe z. B. direkt von der tty lesen. Siehe Q: Why not just use a pipe (popen())?

Sie wahrscheinlich wie pexpect's .interact() etwas wollen (nicht getestet):

#!/usr/bin/env python 
import pexpect # $ pip install pexpect 

child = pexpect.spawnu('ABC') 
child.sendline('1 2 3') 
child.interact(escape_character=None) # give control of the child to the user 
1

Sie für die vierte ganze Zahl Front nach oben fragen kann, dann ist es mit den anderen 3 in entlang senden:

p = subprocess.Popen(['ABC'], stdin=subprocess.PIPE) 
fourth_int = raw_input('Enter the 4th integer: ') 
all_ints = '1 2 3 ' + fourth_int 
p.communicate(input=all_ints) 
+0

Es gibt keinen Grund, nach der vierten Ganzzahl zu fragen, bevor die anderen 3 gesendet werden: 'p.stdin.write ('1 2 3 \ n'); viert = raw_input ('4te int:'); p.stdin.write (vierter); p.stdin.close() ' – jfs

+0

@ J.F.Sebastian - Sie haben Recht. Meins ist eine Möglichkeit, die Arbeit zu erledigen. Es ist nicht der einzige Weg. –