簡體   English   中英

如何檢查兩個管道子進程之一在python中是否失敗?

[英]How can i check if one of two piped subprocess fails in python?

以該代碼為例(tar可以通過-z -J -j壓縮,並且我知道有tarfile特定的模塊,但這代表了一個長期運行的過程)

    from subprocess import Popen, PIPE
    with open('tarball.tar.gz', 'w+') as tarball:
        tarcmd = Popen(['tar', '-cvf', '-', '/home'], stdout=PIPE)
        zipcmd = Popen(['gzip', '-c'], stdin=tarcmd.stdout, stdout=tarball)
        tarcmd.stdout.close()
        zipcmd.communicate()
        # added a while loop that breaks when tarcmd gets a
        # proper return value. Can it be considerate a good
        # solution?
        while tarcmd.poll() is None:
            print('waiting...')

        # test the values and do stuff accordingly

這是在python子進程中傳遞兩個命令的典型示例。 現在檢查zipcmd的返回碼很容易,但是如何檢查tarcmd是否失敗? 如果我檢查它的返回碼,我總是一無所獲(我認為是因為stdout已關閉)。 基本上,如果兩個命令之一失敗,我想引發一個異常。 在bash中有$ PIPESTATUS,我該如何在python中呢?

如果我檢查其返回碼,我總是一無所獲

如果值為None則表示相應的子進程仍處於活動狀態。 順便說一句,不需要循環調用tarcmd.poll() 您可以使用tarcmd.wait()阻止它退出。

模擬shell管道不太容易出錯:

#!/usr/bin/env python
from subprocess import check_call

check_call('set -e -o pipefail; tar -cvf - /home | gzip -c > tarball.tar.gz', 
           shell=True, executable='/bin/bash')

通過顛倒流程初始化順序:

#!/usr/bin/env python
from subprocess import Popen, PIPE

with open('tarball.tar.gz', 'wb', 0) as tarball_file:
    gzip = Popen(['gzip', '-c'], stdin=PIPE, stdout=tarball_file)
tar = Popen(['tar', '-cvf', '-', '/home'], stdout=gzip.stdin)
gzip.communicate()
if tar.wait() != 0 or gzip.returncode != 0:
    raise CalledProcessError

使用shell=True (如果命令是由受信任的輸入(例如源文件中的字符串文字)構造的)或使用諸如plumbum的庫來運行管道,而不是直接在Popen之上實現,可能會更容易。 。

#!/usr/bin/env python
from plumbum.cmd import gzip, tar

(tar['-cvf', '-', '/home'] | gzip['-c'] > 'tarball.tar.gz')()

請參閱如何使用subprocess.Popen通過管道連接多個進程?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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