Во-первых, модуль подпроцесса python является правильным ответом.
В качестве примера подпроцесса:
import subprocess
x = subprocess.check_output(["echo","one","two","three"])
Где x будет выводиться (класс байтов python3: x.decode('utf-8')
для строки)
Обратите внимание, что это не будет дублировать stderr. Если вам нужен также stderr, вы можете сделать что-то вроде:
x = subprocess.check_output(["bash","-c", 'echo foo; echo bar >&2'],stderr=subprocess.STDOUT)
Конечно, есть много других способов захвата stderr, в том числе в другую выходную переменную.
Использование прямого управления
Однако, если вы делаете что-то хитрое и нуждаетесь в прямом контроле, ответ @ Beginner имеет несколько недостатков: был включен os._exit (0), который немедленно приводит к выходу ребенка, делая все остальное бессмысленным. Нет os.execve (), делающего основную цель вопроса бессмысленной. Нет другого способа получить доступ к stdout / stderr ребенка как к другой цели вопроса.
import os
rside, wside = os.pipe()
if not os.fork():
# Child
os.close(rside)
# Make stdout go to parent
os.dup2(wside, 1)
# Make stderr go to parent
os.dup2(wside, 2)
# Optionally make stdin come from nowhere
devnull = os.open("/dev/null", os.O_RDONLY)
os.dup2(devnull, 0)
# Execute the desired program
os.execve("/bin/bash",["/bin/bash","-c","echo stdout; echo stderr >&2"],os.environ)
print("Failed to exec program!")
sys.exit(1)
# Parent
os.close(wside)
pyrside = os.fdopen(rside)
for line in pyrside:
print("Child (stdout or stderr) said: <%s>"%line)
# Prevent zombies! Reap the child after exit
pid, status = os.waitpid(-1, 0)
print("Child exited: pid %d returned %d"%(pid,status))