重定向分叉蟒蛇过程的输出管道

问题描述:

我想从一个分叉Python进程的父写一些记录的过程,所以我用一管为:重定向分叉蟒蛇过程的输出管道

rpipe, wpipe = os.pipe() 

pid = os.fork() 
if pid == -1: 
    raise TestError("Failed to fork() in prepare_test_dir") 

if pid == 0: 
    # Child -- do the copy, print log to pipe and exit 
    try: 
     os.close(rpipe) 
     os.dup2(wpipe, sys.stdout.fileno()) 
     os.dup2(wpipe, sys.stderr.fileno()) 
     os.close(wpipe) 

     self._prepare_test_dir(test) 

     sys.stdout.write(self.copy_log) 
    finally: 
     os._exit(1) 

os.close(wpipe) 

_, status = os.waitpid(pid, 0) 

# XXX: if copy_log is larger than PIPE_BUF (4-8k), everything 
# then is going badly 
outf = os.fdopen(rpipe) 
self.copy_log = outf.read() 

return os.WEXITSTATUS(status) 

它不工作,没有什么出现在self.copy_log。我也试图明确建设标准输出对象与fdopen

sys.stdout = os.fdopen(wpipe, 'w') 

不是工作压力太大。但是,如果我把printdup2前:

if pid == 0: 
    try: 
     print 'HELLO' 
     os.close(rpipe) 
     os.dup2(wpipe, sys.stdout.fileno()) 
     os.dup2(wpipe, sys.stderr.fileno()) 
     ... 

复制日志被成功传递到家长和“HELLO”打印到控制终端。我假设print以某种方式影响sys.stdout(与懒惰初始化或其他)。有任何想法吗?

我在各种Linux平台上使用Python 2.6和2.7。

+0

你正在做硬盘的方式,使用[模块子(https://docs.python.org/2/library/subprocess.html )。 – msw

+0

我知道'subprocess',但我必须使用fork。不幸的是,只能保证fds是关闭的。此外,'fork()'不共享任何内容,它执行所有可写段上的写时复制。 – myaut

该问题似乎不在pipe/dup2相关代码中,而是os._exit。这是杀死python解释器的残酷方法(但对于分叉进程可以,因此它不会触及“共享”对象),但会导致stdoutstderr不会被刷新,并且数据会丢失。

我的孩子来到了下面的代码:

try: 
    os.close(rpipe) 
    os.dup2(wpipe, sys.stdout.fileno()) 
    os.dup2(wpipe, sys.stderr.fileno()) 
    os.close(wpipe) 

    print 'aaaaaaaaa' 
except: 
    traceback.print_exc(20, sys.stderr) 
finally: 
    sys.stdout.flush() 
    sys.stderr.flush() 
    os._exit(1)