【问题标题】:Detecting Popen() errors when shell=True当 shell=True 时检测 Popen() 错误
【发布时间】:2013-02-20 14:39:35
【问题描述】:

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

【问题讨论】:

  • 我不确定我是否理解您的实际问题。你想让我做什么?为什么像subprocess.check_call('date', shell=True) 这样的东西还不够?
  • 您可以通过Non-blocking read on a subprocess.PIPE in python 获取标准错误输出,但不清楚您是否真的需要它。
  • 目前还不清楚你的问题是要判断shell是否执行命令失败,或者如何使用.communicate(),或者你在说什么情况。跨度>
  • +1。相当简洁和详细的答案,没有什么可抱怨的。
  • @phihag 可能是因为PIPEs.

标签: linux python-2.7 subprocess


【解决方案1】:

如果您必须知道它是否失败才能知道是否将数据输入管道,您可以这样做

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

【讨论】:

    【解决方案2】:

    我不会直接回答您的问题,但使用 plumbum 处理此类任务可以让您的生活变得轻松许多。 http://plumbum.readthedocs.org/en/latest/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-25
      • 1970-01-01
      • 2016-03-16
      • 2017-11-06
      • 1970-01-01
      • 1970-01-01
      • 2019-11-23
      • 2011-04-18
      相关资源
      最近更新 更多