Popen([...],stderr = PIPE)忽略来自衍生的python程序的input()消息

时间:2017-08-22 06:12:55

标签: python python-3.x subprocess stdout popen

我有一个文件通过Popen()运行另一个文件。

# a.py
import subprocess

p = subprocess.Popen(['python3','/home/scotty/b.py'], 
stderr=subprocess.PIPE)
p.wait()

# b.py
input('???')

当我运行a.py" ???"没有出现,但提示仍然有效......为什么?我该如何解决?

如果我删除stderr = subprocess.PIPE然后" ???"确实出现了。

根据文档,输入"的输出被写入标准输出"而且我没有触及标准输出。

1 个答案:

答案 0 :(得分:0)

似乎在你的例子中,所有事情都发生了,好像为stderr打开一个管道而不是为stdout打开管道具有将stdout重定向到stderr的效果,因为在我做的测试中,stderr收到了输入的提示。 / p>

下面是一个适用于linux的代码。它可能过于复杂,因为我使用socketpairs,这当然不是必需的,但至少它是健壮的并且它可以工作。

##################################
# a.py

import subprocess
import socket
import select

esock, echildsock = socket.socketpair()
osock, ochildsock = socket.socketpair()
p = subprocess.Popen(['python3','b.py'], 
    stderr=echildsock.fileno(),
    stdout=ochildsock.fileno())

while p.poll() is None:
    r, w, x = select.select([esock, osock],[],[], 1.0)
    if not r:
        continue # timed out
    for s in r:
        print('stdout ready' if s is osock else 'stderr ready')
        data = s.recv(1024)
        print('received', data.decode('utf8'))
osock.shutdown(socket.SHUT_RDWR)
osock.close()
esock.shutdown(socket.SHUT_RDWR)
esock.close()

##################################
# b.py

res = input('???')
print('in b:', res)