【问题标题】:How to get the output from executing shell commands in Python如何从 Python 中执行 shell 命令获取输出
【发布时间】:2020-03-25 00:16:19
【问题描述】:

我正在尝试使用 python 执行这个 shell 命令

但问题是,即使有错,它也不给出输出:

这是我尝试过的:

get_ns_p1 = subprocess.Popen(['kubectl', 'get', 'ns'], stdout=subprocess.PIPE)
get_ns_p2 = subprocess.Popen(["grep", "-E", "\'(^|\s)"+NAMESPACE+"($|\s)\'"], stdin=get_ns_p1.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

get_ns_p1.stdout.close() # Allow proc1 to receive a SIGPIPE if proc2 exits.
out_ns, err = get_ns_p2.communicate()

print("output: " + out_ns)
print("error: " + err)

输出如下:

输出:

错误:

但在终端中,它会显示如下输出:

来自服务器的错误(已经存在):命名空间“namespace-tests”已经存在

如何将这个错误添加到我的err 变量中?

【问题讨论】:

  • 在子进程中运行grep 无论如何都是愚蠢的。只需re.search(r'(?:^|\s){}(?:\s|$)'.format(NAMESPACE)) 上的stdout 来自subprocess.run(['kubectl', 'get', 'ns'], text=True, capture_output=True)
  • 你能给我一个工作示例吗?我是 python 新手。
  • 我几乎做到了。您在哪些部分遇到问题?另见stackoverflow.com/a/51950538/874188
  • ...但是如果您要查找的是错误消息,则应该检查stderr
  • 这里的re 是什么?

标签: python python-2.7 subprocess


【解决方案1】:

您的代码工作正常;问题是,如果 kubectl 完全正确写入,您正试图捕获在 stderr 上发出的字符串。

但是,将grep 作为单独的子进程运行是非常低效且不必要的; Python 本身在re library 中提供了一个功能更强大、更完整的正则表达式引擎,它还可以让您避免启动单独进程的开销。

import re

r = re.compile(r'(?:^|\s){}(?:\s|$)'.format(NAMESPACE))

kube = subprocess.run(['kubectl', 'get', 'ns'], text=True, capture_output=True)
e = []
for line in kube.stderr.split('\n'):
    if r.search(err):
        e.append(line)
err = '\n'.join(line)

如果您受限于没有 subprocess.run() 的旧版 Python,您必须重新实现它,很糟糕。

p = subprocess.Popen(['kubectl', 'get', 'ns'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out_ns, err = p.communicate()
e = []
for line in err.split('\n'):
    ...

这有许多缺陷和缺点;你真的应该认真考虑升级到 Python 3.5+。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2014-06-29
  • 1970-01-01
  • 1970-01-01
  • 2012-10-08
  • 2022-01-16
  • 2013-08-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多