gpt4 book ai didi

python-3.x - 如何在 Python3 的 Popen 中读取/写入文件描述符?

转载 作者:行者123 更新时间:2023-12-02 00:05:29 24 4
gpt4 key购买 nike

在 Popen 中,我可以写入 stdin (0) 并从 stdout (1) 和 stderr (2) 读取。

我想做这样的事情:

#!/usr/bin/env python3
from subprocess import Popen, PIPE
with Popen(
[
'ffmpeg',
'-f', 'matroska', '-i', 'pipe:0',
'-f', 'matroska', '-i', 'pipe:3',
],
stdin=PIPE, in_3=PIPE) as p:
p.stdin.write(b'There is nothing special.')
p.in_3.write(b'\xf0\x9f\x99\x88\xf0\x9f\x99\x89\xf0\x9f\x99\x8a')

最佳答案

stderr , stdoutstdin被特殊对待。当Popen启动一个新进程,它必须创建用于与子进程通信的管道,因此指定一个额外的管道与子进程通信并不是那么简单。

如果您需要另一个管道,则需要在执行子流程之前对其进行设置。

这是一个简单的示例,向您展示如何完成。它执行一个测试脚本,该脚本只是将数据从作为命令行参数(或标准输入)给出的文件描述符复制到标准错误(或标准输出):

测试.sh:

#!/bin/bash

read_fd="$1" # get file descriptor from command line

cat # write stdin to stdout
cat <&"$read_fd" >&2 # read from read_fd and write to stderr

调用程序:ptest.py:
import os
import subprocess

pipe_rfd, pipe_wfd = os.pipe()

print(pipe_rfd, pipe_wfd)

p = subprocess.Popen(
["./test.sh", str(pipe_rfd)],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
close_fds=False, # make sure file descriptors are kept open in subprocess
preexec_fn = lambda: os.close(pipe_wfd) # make sure write end is closed in child
)

p.stdin.write(b'spam\n')
p.stdin.close()

os.write(pipe_wfd, b'eggs\n')
os.close(pipe_wfd)

print('out:', p.stdout.read())
print('err:', p.stderr.read())

在python2中,你需要 close_fds=Falsepreexec_fn在产生子级之前关闭管道的写端,否则如果写端在父级中关闭,则读端将看不到 EOF。从 python3.2 开始,你可以改用新的 pass_fds 提供一个文件描述符列表以保持打开状态的参数,但上面的代码也有效(仅在 linux 上测试)。

应用于您的问题, Popen然后调用看起来像:
...
with Popen(
[
'ffmpeg',
'-f', 'matroska', '-i', 'pipe:0',
'-f', 'matroska', '-i', 'pipe:%d' % pipe_rfd,
],
stdin=PIPE, pass_fds=[pipe_rfd]) as p:
...

关于python-3.x - 如何在 Python3 的 Popen 中读取/写入文件描述符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18684925/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com