![](/img/trans.png)
[英]Python subprocess.Popen: redirection with ">" does not work
[英]Why does `script.py <(cat *.gz)` work with subprocess.Popen in python 2 but not python 3?
我們最近發現,如果腳本是通過進程替換提供其輸入文件的,那么該腳本是我們在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)
順便說一句,我們之所以進行分叉,僅僅是因為命令行gzip的速度明顯快於使用gzip.open的速度,而且腳本是長時間運行的工作程序-區別是數小時。
我們正在針對此問題實施變通方法,但想了解為什么它在python 3中不起作用但在python 2中起作用。
這是新的默認Popen Popen()
family參數close_fds=True
。 您可以使用close_fds=False
顯式覆蓋它,並且繼承的文件描述符將傳遞給子進程(取決於os.set_inheritable()
配置)。
同樣,在Python 3.2和更高版本上,您可以使用pass_fds
列表(如pass_fds=[0,1,2,63]
)使stdin,stdout,stderr和FD#63可用於調用的子進程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.