[英]How can I use a piped string of commands with Python subprocess module?
[英]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')()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.