在Python中运行多个bash行并单独检查它们的状态和输出

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

我试图在Python 3中执行几行bash并分别检查每一行的状态。

我首先尝试使用来自gestatusoutputsubprocess,但是每一行都是在一个不与其他人通信的独立进程中运行的(为了简单起见,给定的MWE包括设置变量,但我打算在实际中做什么代码比这更复杂 - 我知道os.environ这个非常具体的例子):

from subprocess import getstatusoutput as cmd

stat, out = cmd("export TEST=1")
stat, out = cmd("echo $TEST")

因此将返回:

>>> print(out)
(0, "")

然后我尝试了以下内容:

cmdline = """export TEST=1
echo $TEST"""
stat, out = cmd(cmdline)

这有效但迫使我解析输出,特别是如果我想检查第一个命令的状态(如果echo工作,cmd返回的状态是0,无论以前发生过什么),这不是很强大。

我看到一些使用Popen(仍然来自subprocess)的东西,但无法有效地使用它。

任何帮助,将不胜感激!

python python-3.x bash subprocess
2个回答
0
投票

对我来说,你试图在两个进程之间共享环境变量,这是不可能的。它看起来像这样:

Process 1 python main.py                #TEST = "" 
    |Process 2-->"export TEST=1"        #Change Process2 env variable TEST to '1'
    |Process 3-->"echo $TEST"           #Print Process3 env variable TEST (get from process 1)

您可以先使用os.environ []更改当前环境(Process 1变量),然后在fork之后使用该变量。

像这样的东西

import os
import subprocess
import sys

os.environ['TEST'] = '1'
out = subprocess.check_call('echo $TEST',shell = True)

0
投票

我做了以下事情:

  • 创建一个包装launchsubprocess.Popen命令来启动我的bash命令,这使我可以检索当前环境或传递自定义环境
  • 创建一个get_env来解析前一个命令的返回并获得环境的dict

launch wrapper

import os
import subprocess as sp

def launch(cmd_, env=os.environ, get_env=False):
    if get_env: cmd_ += " && printenv"
    load = sp.Popen(cmd_, shell=True, stdout=sp.PIPE, stderr=sp.PIPE, env=env)
    out  = load.communicate()
    err  = load.returncode
    return(err, out)

Retrieve the environment

def get_env(out, encoding='utf-8'):
    lout = str(out[0], encoding).split('\n')
    new_env = {}
    for line in lout:
        if len(line.split('=')) <= 1:
            pass
        else:
            k = line.split("=")[0]
            v = "=".join(line.split("=")[1:])
            new_env[k] = v
    return new_env

(这是一个简单的版本,如果您的环境中有类似功能的东西,它可能会更复杂 - 它会发生。)


Results:

我可以用它如下:

err, out = launch("export TEST=1", get_env=True)
if not err: new_env = get_env(out)
err, out = launch("echo $TEST", env=new_env)

因此:

>>> print(str(out[0], encoding='utf-8'))
1
© www.soinside.com 2019 - 2024. All rights reserved.