【问题标题】:Assign shell script output to python variable ignoring error messages将 shell 脚本输出分配给 python 变量,忽略错误消息
【发布时间】:2015-01-27 17:39:56
【问题描述】:

我有一个 python 脚本,我用它来调用一个重命名文件的 bash 脚本。然后我需要文件的新名称,以便 python 可以对其进行进一步处理。我正在使用 subprocess.Popen 来调用 shell 脚本。 shell 脚本会回显新文件名,因此我可以使用 stdout=subprocess.PIPE 来获取新文件名。

问题在于,有时 bash 脚本会根据具体情况尝试使用旧名称重命名文件,因此通过 mv 命令会给出两个文件相同的消息。我已经剪掉了所有其他的东西,并在下面包含了一个基本示例。

$ ls -1
test.sh
test.txt

这个shell脚本只是一个强制错误信息的例子。

$ cat test.sh
#!/bin/bash
mv "test.txt" "test.txt"
echo "test"

在python中:

$ python
>>> import subprocess
>>> p = subprocess.Popen(['/bin/bash', '-c', './test.sh'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
>>> p.stdout.read()
"mv: `test.txt' and `test.txt' are the same file\ntest\n"

如何忽略来自 mv 命令的消息而只获取 echo 命令的输出?如果一切顺利,shell 脚本的唯一输出将是 echo 的结果,所以我真的只需要忽略 mv 错误消息。

谢谢,

杰兰特

【问题讨论】:

  • 如果您不想在stdout 上看到错误消息,请不要将stderr 发送到stdout
  • 所以你不想知道命令有没有成功?

标签: python bash shell subprocess


【解决方案1】:

直接stderr 为空,因此

$ python
>>> import os
>>> from subprocess import *
>>> p = Popen(['/bin/bash', '-c', './test.sh'], stdout=PIPE, stderr=open(os.devnull, 'w'))
>>> p.stdout.read()

【讨论】:

  • 除非你从管道中读取,否则不要设置stderr=PIPEos.devnull is portable
  • 我认为允许 GC 获取未使用的 PIPE 没有问题。但是os.devnull 是一个我不知道的好技巧。
  • 未读管道是一个等待发生的死锁。计算子流程文档中有关它的警告数。
  • 我想到了这一点,但我认为 OP 是在谈论他脚本中的一行错误。在缓冲区已满(通常为 4k)之前,不会发生任何死锁。但你是对的——这是不好的形式,应该避免。我已经修改了答案
【解决方案2】:

获取子进程的输出并忽略其错误消息:

#!/usr/bin/env python
from subprocess import check_output
import os

with open(os.devnull, 'wb', 0) as DEVNULL:
    output = check_output("./test.sh", stderr=DEVNULL)

如果脚本以非零状态返回,check_output() 将引发异常。

How to hide output of subprocess in Python 2.7

【讨论】:

  • 我假设如果 OP 想忽略 stderr,他也不想要异常,不是吗?
  • 我不这么认为。如果 OP 想完全忽略错误;可以添加显式的try/except
  • 谢谢。尽管在这种情况下我不希望出现异常,但我确信在出现错误时会很有用。
猜你喜欢
  • 2013-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-03
  • 2018-03-12
  • 2011-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多