hunminpark
hunminpark

Reputation: 214

subprocess.Popen - redirect stdin again

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

Answers (2)

jfs
jfs

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

Hai Vu
Hai Vu

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

Related Questions