如何从一个进程环境?(How to get environment from a subproces

2019-06-27 10:35发布

我想通过一个python程序来调用一个过程,但这个过程需要由其他进程设置了一些特定的环境变量。 我怎样才能得到第一个进程的环境变量将它们传递给第二?

这档节目是什么样子:

import subprocess

subprocess.call(['proc1']) # this set env. variables for proc2
subprocess.call(['proc2']) # this must have env. variables set by proc1 to work

但处理不共享相同的环境。 需要注意的是,这些程序是不是我的(第一大又丑.bat文件,第二个专有软件),所以我不能修改它们(好吧,我可以提取所有我从蝙蝠的需要,但它是非常combersome )。

注:我使用Windows,但我更喜欢一个跨平台解决方案(但不会对类Unix系统中的出现我的问题...)

Answer 1:

既然你在Windows中是很明显,你需要一个Windows的答案。

创建一个包装批处理文件,如。 “run_program.bat”,并运行两个程序:

@echo off
call proc1.bat
proc2

该脚本将运行并设置它的环境变量。 两个脚本在同一个解释器(cmd.exe的实例)上运行,所以变量prog1.bat执行PROG2时集被设置。

不是非常漂亮,但它会工作。

(Unix的人,你可以做一个bash脚本同样的事情。“来源file.sh”)



Answer 2:

这里是你如何提取批处理或CMD文件的环境变量,而无需创建一个包装脚本的例子。 请享用。

from __future__ import print_function
import sys
import subprocess
import itertools

def validate_pair(ob):
    try:
        if not (len(ob) == 2):
            print("Unexpected result:", ob, file=sys.stderr)
            raise ValueError
    except:
        return False
    return True

def consume(iter):
    try:
        while True: next(iter)
    except StopIteration:
        pass

def get_environment_from_batch_command(env_cmd, initial=None):
    """
    Take a command (either a single command or list of arguments)
    and return the environment created after running that command.
    Note that if the command must be a batch file or .cmd file, or the
    changes to the environment will not be captured.

    If initial is supplied, it is used as the initial environment passed
    to the child process.
    """
    if not isinstance(env_cmd, (list, tuple)):
        env_cmd = [env_cmd]
    # construct the command that will alter the environment
    env_cmd = subprocess.list2cmdline(env_cmd)
    # create a tag so we can tell in the output when the proc is done
    tag = 'Done running command'
    # construct a cmd.exe command to do accomplish this
    cmd = 'cmd.exe /s /c "{env_cmd} && echo "{tag}" && set"'.format(**vars())
    # launch the process
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=initial)
    # parse the output sent to stdout
    lines = proc.stdout
    # consume whatever output occurs until the tag is reached
    consume(itertools.takewhile(lambda l: tag not in l, lines))
    # define a way to handle each KEY=VALUE line
    handle_line = lambda l: l.rstrip().split('=',1)
    # parse key/values into pairs
    pairs = map(handle_line, lines)
    # make sure the pairs are valid
    valid_pairs = filter(validate_pair, pairs)
    # construct a dictionary of the pairs
    result = dict(valid_pairs)
    # let the process finish
    proc.communicate()
    return result

因此,要回答你的问题,你会创建一个.py文件,做以下操作:

env = get_environment_from_batch_command('proc1')
subprocess.Popen('proc2', env=env)


Answer 3:

正如你所说,进程不共享的环境 - 所以你从字面上问是不可能的,不仅在Python,但与任何编程语言。

可以做的是把环境变量在文件中,或者在管道,要么

  • 有父进程读取它们,并且将它们传递到PROC2创建PROC2之前,或
  • 有PROC2阅读它们,并将它们在本地

后者将需要从PROC2合作; 前者要求PROC2开始前成为变量闻名。



Answer 4:

两件事情映入脑海:(1)使进程共享同一环境中,他们以某种方式结合到同一个过程,或(2)具有包含相关的环境变量的第一过程产生的输出,这样,Python可以读取它,构建用于第二处理环境。 我认为(虽然我不是100%确定),不存在任何方式你希望做的,从子进程获得了环境。



Answer 5:

Python的标准模块多有一个队列系统,让您通过泡菜,能够对象通过流程进行传递。 也进程可以交换使用os.pipe消息(腌对象)。 请记住,资源(例如:数据库连接)和手柄(如:文件句柄)不能腌制。

你会发现这个链接有趣: 与多进程之间的通信

另外,PyMOTw约多处理值得一提: 多基础

对不起我的拼写



Answer 6:

环境是从父进程继承。 设置你的主脚本需要的环境,而不是子(孩子)。



文章来源: How to get environment from a subprocess?