我试图向非python子进程发出shell并允许它从python继承stdin和stdout。 - 我正在使用subprocess.Popen
如果我从控制台调用,这可能会有效,但是当我使用python shell时它肯定不起作用
(我顺便使用IDLE)
有没有办法说服python允许非python子进程将它的stdout打印到python shell?
答案 0 :(得分:6)
这既适用于脚本,也适用于交互式解释器,但不适用于IDLE:
subprocess.Popen(whatever, stdin=sys.stdout, stdout=sys.stdin)
您不能将IDLE分配给sys.stdin
和sys.stdout
的对象用作subprocess.Popen
的参数。这些对象(IDLE shell窗口的接口)是类文件,但它们不是具有fileno
属性的真实文件句柄,而类Unix操作系统需要将fileno指定为stdin或stdout一个子流程。我不能代表Windows,但我想它有类似的要求。
答案 1 :(得分:4)
Taymon的答案直接解决了你的问题,因为IDLE的stdin / stdout实际上是类文件对象,而不是与控制台/终端关联的标准文件流。此外,在Windows IDLE中运行pythonw.exe,它甚至没有附加的win32控制台。
也就是说,如果您只需要将程序的输出实时打印给用户,那么在许多情况下(但不是全部)您可以逐行读取输出并相应地回显它。以下适用于Windows IDLE。它演示了从管道stdout
逐行读取。它还显示了如果进程缓冲管道会发生什么,在这种情况下readline
将阻塞,直到缓冲区已满或管道关闭。可以使用某些程序(例如Python解释器的-u选项)手动禁用此缓冲,并且还有针对Unix的解决方法,例如stdbuf。
test1.py
import sys
import subprocess
def test(cmd):
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
it = iter(p.stdout.readline, b'')
for line in it:
print(line.rstrip().decode('ascii'))
print('Testing buffered subprocess...')
test([sys.executable, 'test2.py'])
print('\nTesting unbuffered subprocess...')
#-u: unbuffered binary stdout and stderr
test([sys.executable, '-u', 'test2.py'])
test2.py:
import time
for i in range(5):
print(i)
time.sleep(1)
IDLE中的输出应如下所示,第一组数字在延迟后一次打印,第二组数字逐行打印。
Testing buffered subprocess...
0
1
2
3
4
Testing unbuffered subprocess...
0
1
2
3
4