我试图在Python 3中执行几行bash
并分别检查每一行的状态。
我首先尝试使用来自gestatusoutput
的subprocess
,但是每一行都是在一个不与其他人通信的独立进程中运行的(为了简单起见,给定的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
)的东西,但无法有效地使用它。
任何帮助,将不胜感激!
对我来说,你试图在两个进程之间共享环境变量,这是不可能的。它看起来像这样:
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)
我做了以下事情:
launch
的subprocess.Popen
命令来启动我的bash命令,这使我可以检索当前环境或传递自定义环境get_env
来解析前一个命令的返回并获得环境的dict
launch
wrapperimport 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