第十章:使用进程、线程和协程提供并发性-subprocess:创建附加进程-与其他命令交互

10.1.4 与其他命令交互
前面的所有例子都假设交互量是有限的。communicate()方法读取所有输出,返回之前要等待子进程退出。也可以在程序运行时从Popen实例使用的各个管道句柄增量地进行读写。可以用一个简单的应答程序来展示这个技术,这个程序从标准输入读,并写至标准输出。
下一个例子中使用脚本repeater.py作为子进程。它从stdin读取,并将值写至stdout,一次处理一行,知道再没有更多输入为止。开始和停止时它还会向stderr写一个消息,显示子进程的生命期。

# repeater.py
import sys

sys.stderr.write('repeater.py: starting\n')
sys.stderr.flush()

while True:
    next_line = sys.stdin.readline()
    sys.stderr.flush()
    if not next_line:
        break
    sys.stdout.write(next_line)
    sys.stdout.flush()

sys.stderr.write('repreter.py: exiting\n')
sys.stderr.flush()

下一个交互例子将采用不同方式使用Popen实例的stdin和stdout文件句柄。在第一个例子中,将把一组5个数写至进程的stdin,每写一个数就读回下一行输出。第二个例子中仍然写同样的5个数,但要使用communicate()一次读取全部输出。

import io
import subprocess

print('One line at a time:')
proc = subprocess.Popen(
    'python3 repeater.py',
    shell=True,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    )
stdin = io.TextIOWrapper(
    proc.stdin,
    encoding='utf-8',
    line_buffering=True,  # Send data on newline
    )

stdout = io.TextIOWrapper(
    proc.stdout,
    encoding='utf-8',
    )

for i in range(5):
    line = '{}\n'.format(i)
    stdin.write(line)
    output = stdout.readline()
    print(output.rstrip())
remainder = proc.communicate()[0].decode('utf-8')
print(remainder)

print()
print('All output at once:')
proc = subprocess.Popen(
    'python3 repeater.py',
    shell=True,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    )
stdin = io.TextIOWrapper(
    proc.stdin,
    encoding='utf-8',
    )
for i in range(5):
    line = '{}\n'.format(i)
    stdin.write(line)
stdin.flush()

output = proc.communicate()[0].decode('utf-8')
print(output)

对于这两种不同的循环,“repeater.py:exiting”行出现在输出的不同位置上。
运行结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43193719/article/details/89478025