当shell = True时检测Popen()错误

时间:2013-03-06 00:09:24

标签: linux python-2.7 subprocess

我想在该用户的$SHELL中执行任意用户提供的命令。该命令可能是短命的(如ls)或长寿命的(如firefox),它可能是单个命令,管道或任何其他shell支持的构造。

执行方法必须代表shell指示成功或失败,并且必须不阻止,无论命令何时或是否终止。该命令可能从不终止,直到执行方法返回并且我的程序继续。

带有Popen()

shell=True不会阻止,但也不表示失败。 subprocess辅助函数确实阻塞,在这里没用。 Popen.poll()(在this question中建议)返回None,直到命令终止,并且在失败时不立即返回非None(必须重复调用,直到shell终止)。

作为期望行为的一个例子

prog1 = shell_run('blocking_prog', stdin=PIPE, stdout=PIPE)
prog2 = shell_run('nonsense_prog', stdin=PIPE, stdout=PIPE)

第一行应该将Popen对象分配给prog1,第二行应该引发OSError或类似对象。

我是否认为在这些条件下可靠地检测Popen()错误是不正确的?

2 个答案:

答案 0 :(得分:1)

我没有直接回答您的问题,但使用plumbum执行此类任务可以让您的生活变得更加轻松。 http://plumbum.readthedocs.org/en/latest/

答案 1 :(得分:0)

如果为了知道是否管道数据而必须知道它是否失败,你可以做到

prog2 = shell_run('nonsenseprog', stdin=PIPE, stdout=PIPE,
               shell=True, executable=os.getenv('SHELL'))
# If the program does not exist, it should fail immediately and .poll() knows about that.
# If it exists and runs, `.poll()` returns None.
if prog2.poll() is not None:
    raise Whatever # it failed

或者,您可以检查是否确实需要shell=True