错误检查在python中为unix创建的管道命令

时间:2012-12-17 18:32:07

标签: python unix filesystems pipe file-handling

我正在编译一个从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输出还包含一些输出,依此类推?感谢。

3 个答案:

答案 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(在你处理任何内容时使用,当你读入一个小缓冲区而不是在内存中加载整个输出时)。

所以你需要做的就是:

  • 应该使用字符串,而不是args的列表
  • 使用shell = True
  • 使用executable =“/ bin / bash”

代码:

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')