python:不带外部命令的fork,并分别捕获stdout和stderr

问题描述 投票:1回答:1

我想在python中派生一个不运行外部命令的子进程...它将只运行一个已定义的函数。我想分别捕获stdoutstderr

我知道如何使用os.fork()os.pipe(),但是该机制只给了我两个fd。我正在寻找三个fd:一个用于stdin,一个用于stdout和一个用于stderr。运行外部命令时,使用subprocess.Popen易于管理,但是该函数似乎不允许派生局部函数;只有一个单独的可执行文件。

在ruby中,popen3命令可以将“-”作为其命令参数,在这种情况下,发生分叉而没有调用任何外部命令,并且返回了我提到的3个fd。是否在python中有与此例程类似的python类似物?

python fork stdout stderr
1个回答
1
投票
  • 如果要从子进程中分别重定向stdoutstderr,则可以简单地为每个子进程创建两个单独的管道,而不是一个。我已经分享了相关代码。

  • 您也可以阅读此主题以获取有关此主题的更多知识:Redirect stdout to a file in Python?

  • 我已经提到了两种写入stdout和子进程(Method1Method2)的stderr的方法

  • 如果您还想写入子进程的stdin,则应创建另一个文件描述符。这次r将转到子进程,而w将转到父进程。

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)


© www.soinside.com 2019 - 2024. All rights reserved.