Python 如何在子流程完成运行后获取其环境变量?
我正在寻找一种方法来实现这一点,这样我就可以将它传递到另一个子流程的环境。您能在第一个子流程中打印出来并用python处理该字符串吗?不幸的是,孩子的环境一退出就会消失,即使您使用特殊文件Python 如何在子流程完成运行后获取其环境变量?,python,environment-variables,subprocess,Python,Environment Variables,Subprocess,我正在寻找一种方法来实现这一点,这样我就可以将它传递到另一个子流程的环境。您能在第一个子流程中打印出来并用python处理该字符串吗?不幸的是,孩子的环境一退出就会消失,即使您使用特殊文件/proc/[pid]/环境它不会反映子进程所做的更改 即使上述方法确实有效,您也会有一个竞争条件:家长需要确定阅读环境的“正确时间”,最好是在孩子修改环境之后。要做到这一点,父母需要与孩子协调,而只要你在协调,你也可以明确地进行沟通 您需要通过套接字、管道、共享内存等在父级和子级之间传递状态。可以使这变得更容
/proc/[pid]/环境
它不会反映子进程所做的更改
即使上述方法确实有效,您也会有一个竞争条件:家长需要确定阅读环境的“正确时间”,最好是在孩子修改环境之后。要做到这一点,父母需要与孩子协调,而只要你在协调,你也可以明确地进行沟通
您需要通过套接字、管道、共享内存等在父级和子级之间传递状态。可以使这变得更容易,允许您通过队列或管道将数据从子级传递到父级
已更新下面是使用多处理
模块让父进程与子进程共享值,并让子进程通过队列彼此通信的简要说明。这使它变得非常简单:
import os
from multiprocessing import Process, Manager, Queue
def worker1(d, q):
# receive value from worker2
msg = q.get()
d['value'] += 1
d['worker1'] = os.getpid(), msg
def worker2(d, q):
# send value to worker1
q.put('hi from worker2')
d['value'] += 1
d['worker2'] = os.getpid()
if __name__ == '__main__':
mgr = Manager()
d = mgr.dict()
q = Queue()
d['value'] = 1
p1 = Process(target=worker1, args=(d,q))
p1.start()
p2 = Process(target=worker2, args=(d,q))
p2.start()
p1.join()
p2.join()
print d
结果:
{'worker1': (47395, 'hi from worker2'), 'worker2': 47396, 'value': 3}
在Windows中,您可以使用SET命令获取所需内容,如下所示:
import os, tempfile, subprocess
def set_env(bat_file):
''' Set current os.environ variables by sourcing an existing .bat file
Note that because of a bug with stdout=subprocess.PIPE in my environment
i use '>' to pipe out the output of 'set' into a text file, instead of
of using stdout. So you could simplify this a bit...
'''
# Run the command and pipe to a tempfile
temp = tempfile.mktemp()
cmd = '%s && set > %s'%(bat_file,temp)
login = subprocess.Popen(cmd, shell=True)
state = login.wait()
# Parse the output
data = []
if os.path.isfile(temp):
with open(temp,'r') as file:
data = file.readlines()
os.remove(temp)
# Every line will set an env variable
for env in data:
env = env.strip().split('=')
os.environ[env[0]] = env[1]
# Make an environment variable
os.environ['SOME_AWESOME_VARIABLE']='nothing'
# Run a batch file which you expect, amongst other things, to change this env variable
set_env('C:/do_something_awesome.bat')
# Lets see what happened
os.environ['SOME_AWESOME_VARIABLE']
// RESULT: 'AWESOME'
因此,现在如果您可以使用它来读取.bat文件,然后使用它生成的环境变量,请对它们进行修改/添加,然后传递到一个新进程。。。等等。这里有一个简单的函数,它在子流程中运行命令,然后将其环境提取到当前流程中 它基于Fnord的版本,没有tempfile,并带有一条标记线,用于区分SET命令和进程本身的任何输出。它不是防弹的,但对我来说是有用的
def setenv(cmd):
cmd = cmd + ' && echo ~~~~START_ENVIRONMENT_HERE~~~~ && set'
env = (subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
.stdout
.read()
.decode('utf-8')
.splitlines())
record = False
for e in env:
if record:
e = e.strip().split('=')
os.environ[e[0]] = e[1]
elif e.strip() == '~~~~START_ENVIRONMENT_HERE~~~~':
record = True
这取决于shell,我相信。顺便说一句,谢谢大家的帮助。是的,但是有没有更漂亮的方法,使我不必从env解析脚本?好吧,我最后做了这个。这似乎是最简单的方法…嗨,我不需要在父进程和子进程之间交换环境,而是在子进程之间交换环境。尝试获取进程环境的限制仍然适用。我已经更新了我的答案,简要介绍了如何使用多处理模块让两个孩子彼此通信,并与家长共享数据。希望能有帮助。