簡體   English   中英

為什么`script.py <(cat * .gz)`在python 2中與subprocess.Popen一起使用,但在python 3中卻不起作用?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM