Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检查python for unix中的管道命令时出错_Python_Unix_Filesystems_Pipe_File Handling - Fatal编程技术网

检查python for unix中的管道命令时出错

检查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条

我正在从python编译一个要在unix系统上执行的命令,其中包含多个管道步骤。e、 g:

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