在Python中运行多个bash行,并分别检查其状态和输出

时间:2019-01-24 08:26:53

标签: python python-3.x bash subprocess

我试图在Python 3中执行多行sql = """\\timing select count(*) from mytable;""" ,并分别检查每行的状态。

我首先尝试使用bash中的gestatusoutput,但是每一行都在一个单独的进程中运行,该进程不与其他行进行通信(为简单起见,给定的MWE包括设置一个变量,但是我打算在我的实际代码中做的比这更复杂-对于这个非常具体的示例,我知道subprocess

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),但是无法有效地使用它。

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:0)

我完成了以下操作:

  • 创建一个launch来包装subprocess.Popen的命令以启动我的bash命令,此外,它还允许我检索当前环境或传递自定义环境
  • 创建一个get_env来解析上一条命令的返回结果,并获得一个dict的环境

launch包装器

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)

获取环境

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

(这是一个简单的版本,如果您的环境中有诸如函数之类的东西,事情可能会更复杂。)


结果:

我可以按如下方式使用它:

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