Reputation: 214
Let's assume there's a program named 'ABC', which reads 4 integers from stdin and does something with them.
Recently, I leanred that we can use pipeline to feed the inputs to ABC, like following :
# send.py
import subprocess
p = subprocess.Popen(['ABC'], stdin = subprocess.PIPE)
print >>p.stdin, '1 2 3 4'
My question is : Can we redirect stdin again after calling subprocess.Popen
?? For example,
# 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 that we can input 4th integer to ABC by typing on the terminal.
Upvotes: 2
Views: 767
Reputation: 414159
The redirection occurs before ABC
is executed e.g., (on Unix) after the fork()
but before execv()
(look at dup2()
calls). It is too late to use the same OS level mechanism for the redirection after Popen()
returns but you could emulate it manually.
To "redirect p.stdin
to terminal's stdin" while the process is running, call shutil.copyfileobj(sys.stdin, p.stdin)
. There could be buffering issues and the child process may read outside its standard input e.g., directly from the tty. See Q: Why not just use a pipe (popen())?
You probably want something like pexpect
's .interact()
(not tested):
#!/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
Upvotes: 1
Reputation: 40688
You can ask for the fourth integer up front, then send it in along with the other 3:
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)
Upvotes: 1