我正在编译一个从python在unix系统上执行的命令,包含多个管道步骤。 e.g:
grep foo myfile | cmd1 | cmd2 > output
这些对应于foo
中包含myfile
的条目的一系列转换。我有时将它构造为由os.system
执行的命令,在其他情况下使用subprocess
模块执行。
如何从Python中对管道的每个部分进行错误检查?例如,在99%的情况下,foo
中有myfile
个条目,其余管道正常工作。但是,如果由于某种原因myfile
存在但不包含foo
条目,则管道的其余部分会中断,因为您正在管道空文件,而其余命令需要非空输入才能工作。这使得调试变得困难,因为你看到的只是破裂管道的输出,而不知道哪个中间步骤失败了。
有没有办法在Python中构建错误检查中间步骤的管道?例如。检查管道的grep
部分是否确实包含一些输出,cmd1
输出上的grep
输出还包含一些输出,依此类推?感谢。
答案 0 :(得分:0)
这是我在Python 2.6 Linux上测试的方法。
a。定义方法
def run_command(command):
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
return (p.returncode, out, err)
b。以下列方式使用
def test_run_command_pipestatus(self):
# the exit $PIPESTATUS is the return code of "exit 2". The default return code is the return code of last command in the pipe
return_code, out, err = run_command("exit 2 | tail -n 1; exit $PIPESTATUS")
print "return_code = %d" %return_code
print out
print err
self.assertEqual(2, return_code)
答案 1 :(得分:0)
基本上与Mingjiang Shi的答案相同,它主要包含您需要的所有关键信息,但没有额外的功能,并且解决了问题。 (并在python 2.7.12和3.5.2中测试)
$ PIPESTATUS在sh中不存在,因此如果您的发行版没有像/bin/sh
那样的bash
(例如使用{{1}的Ubuntu),则必须将可执行文件设置为bash })。它是一个数组,所以我更喜欢使用它。
我建议使用dash
而不是wait()
,这样你就可以过滤而不是slurp(在你处理任何内容时使用,当你读入一个小缓冲区而不是在内存中加载整个输出时)。
所以你需要做的就是:
代码:
communicate()
答案 2 :(得分:0)
这是我的方法,无论如何使用管道命令。它是所有状态码的总和,然后返回结果 用命令替换“ echo 1 | echo 2”或“ cat test | echo 2”
>> getstatusoutput('status = 0; echo 1 | echo 2; for((i = 0; i <$ {#PIPESTATUS [*]}; i ++)));执行let status = $ {status} + $ {PIPESTATUS [$ {i}]};完成;退出$ status')
(0,'2')
>> getstatusoutput('status = 0; cat test | echo 2; for((i = 0; i <$ {#PIPESTATUS [*]}; i ++)));执行let status = $ {status} + $ {PIPESTATUS [$ {i}]};完成;退出$ status')
(1,'2 \ ncat:test:No such file or directory')