python:没有外部命令的fork,并分别捕获stdout和stderr [英] python: fork without an external command, and capturing stdout and stderr separately
问题描述
我想在不运行外部命令的python中派生一个子进程...它将只运行定义的函数.我想分别捕获stdout
和stderr
.
I'd like to fork a subprocess in python that does not run an external command ... it would just run a defined function. And I want to capture stdout
and stderr
separately.
我知道如何使用os.fork()
和os.pipe()
,但是该机制只给了我两个fd.我正在寻找三个fd:一个用于stdin
,一个用于stdout
和一个用于stderr
.在运行外部命令时,使用subprocess.Popen
可以很容易地进行管理,但是该功能似乎不允许分叉本地功能.只是一个单独的可执行文件.
I know how to use os.fork()
and os.pipe()
, but that mechanism only gives me two fd's to work with. I'm looking for three fd's: one for stdin
, one for stdout
, and one for stderr
. This is easy to manage using subprocess.Popen
when running an external command, but that function doesn't seem to allow a local function to be forked; only a separate executable.
在ruby中,popen3
命令可以将-"作为其命令参数,在这种情况下,发生分叉而没有调用任何外部命令,并且返回了我提到的3个fd.在python中是否有某种类似于该例程的python类似物?
In ruby, the popen3
command can take "-" as its command argument, and in this case, a fork takes place without any external command being invoked, and the 3 fd's I mentioned are returned. Is there some sort of python analog to this routine in python?
推荐答案
-
如果要从子进程中分别重定向
stdout
和stderr
,则可以简单地为每个子进程创建两个单独的管道,而不是一个.我已经分享了相关代码.If you want to redirect the
stdout
andstderr
separately from the child process, you can simply create two separate pipes for each, instead of one. I have shared the relevant code.You can also read this thread to gain more knowledge on this subject: Redirect stdout to a file in Python?
我提到了从子进程(
Method1
,Method2
)写入stdout和stderr的两种方法I have mentioned two methods for writing to stdout, and stderr from the child process (
Method1
,Method2
)如果还想写入子进程的stdin,则应创建另一个文件描述符.这次
r
将转到子进程,而w
将转到父进程.If you want to write to stdin of child process as well, you should create another file descriptor. This time the
r
would go to child process, and thew
would go to the parent process.import os import sys import time # Create two pipes. One for sys.stdout, and one for sys.stderr r_out, w_out = os.pipe() r_err, w_err = os.pipe() pid = os.fork() if pid == 0: # Child process os.close(r_out) os.close(r_err) w1 = os.fdopen(w_out, "w") w2 = os.fdopen(w_err, "w") sys.stdout = w1 sys.stderr = w2 # Note that flush=True is necessary only if you want to ensure the order of messages printed # across method1, and method2 is maintained # Method 1: Standard Python print messages print("Redirected to stdout #2", flush=True) print("Redirected to stderr #2", file=sys.stderr, flush=True) # Method 2: Using system file descriptors stdout_fd = sys.stdout.fileno() os.write(stdout_fd, b'Redirected to stdout') stderr_fd = sys.stderr.fileno() os.write(stderr_fd, b'Redirected to stderr') # Restore original stdout, and stderr sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ # Close the file descriptors w1.close() w2.close() else: # Parent process os.close(w_out) os.close(w_err) r1 = os.fdopen(r_out) r2 = os.fdopen(r_err) for i in range(5): # Note that r1.read(), and r2.read() are non-blocking calls # You can run this while loop as long as you want. print("Read text (sysout):", r1.read()) print("Read text (syserr):", r2.read()) time.sleep(0.5)
这篇关于python:没有外部命令的fork,并分别捕获stdout和stderr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!