如何获取python执行的shell命令的最终输出

时间:2019-11-29 12:28:41

标签: python subprocess

我正在尝试执行Shell命令kubectl get ns | grep -E '(^|\s)namespace-test($|\s)' 但是即使有错误也没空。

导致错误和非错误情况的原因,我都空了,因为它两次执行了命令(|左右的命令),但是我需要是获取实际输出作为返回值,如果有输出,则说0,如果没有输出,则说1

这是我正在尝试的:

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(out_ns)

有人可以帮我吗?

或者如果您对此有任何方法,这就是我想要做的...

我想执行一个带有pipe的shell命令并获取输出,如果有输出,它应该返回一些值,如果输出为空,它应该给出一个不同的值,如果有error,则应提供另一个不同的输出

我该如何实现?

1 个答案:

答案 0 :(得分:0)

Python 2.7-3.x

在CentO上测试

首先,您必须按管道拆分命令。像这样:[command for command in cmd.partition('|') if command != '|' if command != '']

此后,您必须启动subprocess.Popen命令。第一次执行列表中的第一项,之后您可以执行下一个元素,但是必须传递到上一次执行的结果stdin。这将允许您执行管道命令。

但是,请注意shell=True。更多信息here

示例代码

import logging
import subprocess  # nosec

logging.basicConfig(filename='log.log',
                    filemode='a',
                    format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
                    datefmt='%H:%M:%S',
                    level=logging.INFO)

log = logging.getLogger(__name__)


def execute_and_create_output_from_cmd(cmd_parts):
    """
    Functions executes cmd and adds parsed lines to <List> result.
    :return: <List>
    """
    try:
        index = 0
        process = {}
        for cmd_part in cmd_parts:
            cmd_part = cmd_part.strip()
            if index == 0:
                process[index] = subprocess.Popen(cmd_part, shell=True,  # nosec
                                                  stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            else:
                process[index] = subprocess.Popen(cmd_part, shell=True,  # nosec
                                                  stdin=process[index - 1].stdout, stdout=subprocess.PIPE,
                                                  stderr=subprocess.PIPE)
            index += 1
        (output, err) = process[index - 1].communicate()
        exit_code = process[0].wait()

        if exit_code != 0:
            log.warning('Output: %s', output)
            log.error('Error: %s', err)
            log.error('Exit code: %s', exit_code)
        else:
            print(output)  # do whatever you want with your output
    except OSError as os_error:
        log.error('Could not execute command: %s', os_error)


def split_cmd(cmd):
    """ Split cmd command. Check if command contains '|'. '||' allowed. """
    return [command for command in cmd.partition('|') if command != '|' if command != '']


if __name__ == '__main__':
    cmd = split_cmd('ls -al | grep ibm')
    execute_and_create_output_from_cmd(cmd)

我已添加logging。没必要。

输出:

[kchojnowski@zabbix4-worker1 ~]$ python test.py
drwxrwxr-x  2 kchojnowski kchojnowski    50 Jul 24 15:33 ibm_mq