简体   繁体   English

如何在 Python 中获取执行 shell 命令的输出

[英]How to get the output from executing shell commands in Python

I am trying to execute this shell command using python我正在尝试使用python执行此 shell 命令

but the problem is, it doesn't give the output even if there is a wrong or not:但问题是,即使有错误,它也不会给出输出:

This is what I have tried:这是我试过的:

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)

The output looks like:输出看起来像:

output:输出:

error:错误:

but in the terminal itseld, it shows an output like this:但在终端本身,它显示如下输出:

Error from server (AlreadyExists): namespaces "namespace-tests" already exists来自服务器的错误(AlreadyExists):命名空间“namespace-tests”已经存在

how can I this error to my err variable?我怎么能把这个错误告诉我的err变量?

Your code works correctly;您的代码工作正常; the problem is that you are attempting to capture a string which is emitted on stderr if kubectl is at all correctly written.问题是如果kubectl完全正确写入,您正试图捕获在stderr上发出的字符串。

However, running grep as a separate subprocess is quite inefficient and unnecessary anyway;然而,无论如何,将grep作为一个单独的子进程运行是非常低效和不必要的; Python itself features a much more featureful and complete regular expression engine in the re library which also lets you avoid the overhead of starting a separate process. Python 本身在re中提供了一个功能更强大和更完整的正则表达式引擎,它还可以让您避免启动单独进程的开销。

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)

If you are confined to an older version of Python which doesn't have subprocess.run() , you have to reimplement it, poorly.如果您局限于没有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'):
    ...

This has a number of flaws and drawbacks;这有许多缺陷和缺点; you really should be thinking seriously about upgrading to Python 3.5+.你真的应该认真考虑升级到 Python 3.5+。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM