", " " ps , , select fcntl, .. stdout/stderr .
: A B (cmd, ), B C (), A , B EOF:
import os
from select import select
from subprocess import Popen, PIPE
p = Popen(cmd, stdout=PIPE, stderr=PIPE, bufsize=0)
read_set = [p.stdout, p.stderr]
pipename = {p.stdout: "stdout", p.stderr: "stderr"}
timeout = 0.5
while read_set and p.poll() is None:
for pipe in select(read_set, [], [], timeout)[0]:
data = os.read(pipe.fileno(), 1<<30)
if data:
print("got from %s: %r" % (pipename[pipe], data))
else:
pipe.close()
read_set.remove(pipe)
print("exit code %s" % (p.wait(),))
for pipe in read_set:
print("read the rest of %s: %r" % (pipename[pipe], pipe.read()))
pipe.close()
cmd:
import sys
from textwrap import dedent
cmd = [sys.executable, '-u', '-c', dedent("""
# inception style
import os
import sys
from subprocess import Popen
from textwrap import dedent
Popen([sys.executable, '-u', '-c', dedent('''
import os
import sys
import time
time.sleep(60)
print("grandchild %d done" % os.getpid())
sys.stderr.write("grandchild stderr")
sys.exit(20)
''')]) # stdout/stderr are not redirected
print('child %d done' % os.getpid())
sys.stderr.write('child stderr')
sys.exit(19)
""")]