我想在该用户的$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()
错误是不正确的?
答案 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
。