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

Linux 当shell=True时检测Popen()错误,linux,python-2.7,subprocess,Linux,Python 2.7,Subprocess,我想在该用户的$SHELL中执行用户提供的任意命令。该命令可以是短期的(如ls)或长期的(如firefox),也可以是单个命令、管道或任何其他shell支持的构造 执行方法必须代表shell指示成功或失败,并且无论命令何时或是否终止,都不得阻塞。在执行方法返回并且我的程序继续之前,命令可能永远不会终止 Popen()withshell=True不会阻塞,但也不会指示故障。子流程辅助函数不会阻塞,在这里不有用Popen.poll()(在中建议)在命令终止之前返回None,失败时不立即返回non-N

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

执行方法必须代表shell指示成功或失败,并且无论命令何时或是否终止,都不得阻塞。在执行方法返回并且我的程序继续之前,命令可能永远不会终止

Popen()
with
shell=True
不会阻塞,但也不会指示故障。
子流程
辅助函数不会阻塞,在这里不有用
Popen.poll()
(在中建议)在命令终止之前返回
None
,失败时不立即返回non-
None
(必须重复调用,直到shell终止)

作为所需行为的示例

prog1 = shell_run('blocking_prog', stdin=PIPE, stdout=PIPE)
prog2 = shell_run('nonsense_prog', stdin=PIPE, stdout=PIPE)
第一行应将
Popen
对象分配给
prog1
,第二行应产生
OSError
或类似错误


我认为在这种情况下不可能可靠地检测到
Popen()
错误,这是正确的吗?

我不是直接回答你的问题,但使用
plumbum
来完成这些任务可以让你的生活轻松得多

如果为了知道是否导入数据而必须知道它是否失败,那么可以这样做

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

我不确定是否理解您的实际问题。你想做什么?为什么像
subprocess.check_call('date',shell=True)
这样的东西是不够的?您可以做些什么来获取stderr输出,但不清楚您是否真的需要它。您的问题的重点是否是告诉shell是否未能执行命令,或者如何使用.communicate(),或者你说的是什么情况。答案非常简洁详细,没有什么可抱怨的。@phihag可能是因为管道的缘故。