gpt4 book ai didi

python - 为什么 `script.py <(cat *.gz)` 在 python 2 中可以与 subprocess.Popen 一起使用,但在 python 3 中却不能?

转载 作者:行者123 更新时间:2023-12-01 00:44:22 26 4
gpt4 key购买 nike

我们最近发现,如果我们通过进程替换提供输入文件,我们在 python 3.x(但不是 python 2.x)中开发的脚本会被阻塞,例如:

script.py <(cat *.gz)

我们已经使用 gzip 以外的命令(例如 cat)进行了测试,只是为了看看是否会出现类似的错误。他们都提示 /dev/fd/63 (或 /dev/fd/63.gz)不存在。这是(简化的)相关代码:

def open_gzip_in(infile):
'''Opens a gzip file for reading, using external gzip if available'''

# Determine whether to use the gzip command line tool or not
if exeExists('gzip'):
cmd = ['gzip', '-dc', infile]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, bufsize=-1,
universal_newlines=True)
if sys.version.startswith("2"):
with p.stdout:
for line in iter(p.stdout.readline, b''):
yield line
else:
with p:
for line in p.stdout:
yield line
exit_code = p.wait()
if exit_code != 0:
raise subprocess.CalledProcessError(
p.returncode, subprocess.list2cmdline(cmd), 'Ungzip failed')
else:
with io.TextIOWrapper(io.BufferedReader(gzip.open(infile))) as f:
for line in f:
yield(line)

顺便说一句,我们进行 fork 仅仅是因为命令行 gzip 比使用 gzip.open 快得多,而且我们的脚本是一个长时间运行的工作程序 - 差异是多个小时。

我们正在针对此问题实现解决方法,但想了解为什么它在 python 3 中不起作用但在 python 2 中起作用。

最佳答案

这是新的默认 Popen() 系列参数 close_fds=True 的副作用。您可以使用 close_fds=False 显式覆盖它,您继承的文件描述符将传递给子进程(需通过 os.set_inheritable() 配置)。

同样,在 Python 3.2 及更高版本上,您可以使用 pass_fds 列表(如 pass_fds=[0,1,2,63])来创建标准输入、stdout、stderr 和 FD #63 可用于调用的子进程。

关于python - 为什么 `script.py <(cat *.gz)` 在 python 2 中可以与 subprocess.Popen 一起使用,但在 python 3 中却不能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57098553/

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