检查python for unix中的管道命令时出错
我正在从python编译一个要在unix系统上执行的命令,其中包含多个管道步骤。e、 g:检查python for unix中的管道命令时出错,python,unix,filesystems,pipe,file-handling,Python,Unix,Filesystems,Pipe,File Handling,我正在从python编译一个要在unix系统上执行的命令,其中包含多个管道步骤。e、 g: grep foo myfile | cmd1 | cmd2 > output 这些对应于对从myfile中包含foo的条目进行的一系列转换。我有时将其构造为一个命令,由os.system执行,在其他情况下使用子流程模块执行 如何从Python对管道的每个部分进行错误检查?例如,在99%的情况下,myfile中有foo条目以及剩余的管道工程。但是,如果由于某种原因,myfile存在,但不包含foo条
grep foo myfile | cmd1 | cmd2 > output
这些对应于对从myfile
中包含foo
的条目进行的一系列转换。我有时将其构造为一个命令,由os.system
执行,在其他情况下使用子流程
模块执行
如何从Python对管道的每个部分进行错误检查?例如,在99%的情况下,myfile
中有foo
条目以及剩余的管道工程。但是,如果由于某种原因,myfile
存在,但不包含foo
条目,则其余的管道会断开,因为您正在管道传输空文件,其余的命令需要非空输入才能工作。这使得调试变得很困难,因为您所看到的只是断开管道的输出,而不知道哪个中间步骤失败了
有没有一种方法可以在Python中构造错误检查中间步骤的管道?例如,检查管道的
grep
部分是否确实包含一些输出,检查grep
输入的cmd1
输出是否也包含一些输出,依此类推?谢谢。这是我的方法,在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)
基本上与石明江的答案相同,其中包含了您所需的大部分关键信息,但没有额外的功能,并且解决了一个问题。(并在python 2.7.12和3.5.2中进行了测试) $PIPESTATUS在sh中不存在,因此如果您的发行版没有类似于bash的
/bin/sh
(例如使用破折号的Ubuntu),则必须将executable设置为bash。它是一个数组,所以我更喜欢像数组一样使用它
我建议使用wait()
而不是communicate()
,这样您就可以进行过滤而不是slurp(在处理任何输出之前,在读取到小缓冲区时使用,而不是在内存中加载整个输出)
因此,您需要做的就是:
- 应使用字符串,而不是参数列表
- 使用shell=True
- 使用executable=“/bin/bash”
代码:
这是我的方法,不管mutch管道如何命令。它是所有状态代码的总和,并随结果退出
“echo 1 | echo 2”或“cat测试| echo 2”替换为您的命令
>>getstatusoutput('status=0;echo 1 | echo 2;用于((i=0;最简单的方法是在Python中以本机方式进行操作。从操作系统和Python来回调用只会引入额外的变量和复杂性,而这通常是首先要避免的。那么,如果Python需要调用外部命令,您将如何在Python中执行呢?我知道的唯一方法是子进程
。我无法重写编写我在PythonIn bash中调用的所有命令你有PIPESTATUS变量——如果可以的话就使用它。否则就像sr2222建议的那样在python中执行它——设置管道,启动带有重定向输入输出的程序,检查它们的退出状态,这有什么问题吗?你提到的模块甚至将stdin/stdout/stderr作为参数特尔斯!
p = subprocess.Popen("false | true; exit ${PIPESTATUS[0]}", shell=True, executable='/bin/bash', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# at this point you do your filtering, eg. using p.stdout.readinto(buf)
p.wait()
if p.returncode != 0:
# handle it here