将命令标准输出写入控制台和文件(实时)— Python 3.5 + subprocess.run()

问题描述 投票:0回答:1

平台:rhel6(64位)上的Python 3.5

场景

:执行运行作业的Bash命令。每隔几秒钟,此作业将几行输出返回到stdout。

命令

./run_job --name 'myjob' --config_file ./myconfig.conf

目标

:我正在尝试使用Python的subprocess.run()运行上面的命令并捕获该进程的标准输出,将其打印到控制台并将其保存到文件中。我需要在输出可用(实时)时将其打印出来。

我尝试过的内容

:我已经对此进行了广泛的搜索,发现的每个解决方案都在使用subprocess.Popen()This method有点奏效,但是实现它导致破坏了我当前拥有的返回逻辑。从Python documentation读取之后,subprocess.run()方法是从Python 3.5开始的推荐方法,因此这就是我要采用这种方法的原因。

我的设置

:到目前为止,我有一个公用文件,用于记录并运行下面的shell命令。
def setup_logging(log_lvl="INFO"):
    script_name = path.splitext(path.basename(__file__))[0]
    log_path = environ["HOME"] + "/logs/" + script_name + ".log"

    logging.basicConfig(
        level=getattr(logging, log_lvl.upper()),
        format="%(asctime)s: [%(levelname)s] %(message)s",
        handlers=[
            logging.FileHandler(filename=log_path, mode="w", encoding="utf-8"),
            logging.StreamHandler()
        ]
    )

def run_shell(cmd_str, print_stdout=True, fail_msg=""):
    logger = logging.getLogger()
    result = run(cmd_str, universal_newlines=True, shell=True, stderr=STDOUT, stdout=PIPE)

    cmd_stdout = result.stdout.strip()
    cmd_code = result.returncode
    if print_stdout and cmd_stdout != "":
        logger.info("[OUT] " + cmd_stdout)
    if cmd_code != 0 and fail_msg != "":
        logger.error(fail_msg)
        exit(cmd_code)
    return cmd_code, cmd_stdout

所以我将使用以下代码来运行我的脚本:

run_shell("./run_job --name 'myjob' --config_file ./myconfig.conf", fail_msg="Job failed.")

这部分起作用,但是仅在过程完成时才打印完整的标准输出。因此终端将挂起,直到发生这种情况。我需要以实时方式逐行打印stdout,以便可以由记录器编写。

有什么方法可以在不检查现有代码的情况下进行此操作吗?任何帮助,将不胜感激。

平台:rhel6(64位)上的Python 3.5方案:执行一个运行作业的Bash命令。每隔几秒钟,此作业将几行输出返回到stdout。命令:./run_job --name'myjob'--...

python logging subprocess python-3.5
1个回答
0
投票

尝试使用线程和轮询一段时间后,我无法完全正常工作。但是,在由[[Todd

© www.soinside.com 2019 - 2024. All rights reserved.