我想打电话给一个进程,通过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

但处理不同的环境。注意,这些程序不是我(先是大的,丑陋的.蝙蝠文件和第二个专有软),所以我不能修改它们(ok,我可以提取所有我需要的.蝙蝠但这是非常combersome).

注:我使用的窗口,但我更喜欢一个交叉平台方案(但是我的问题就不会发生在类Unix...)

有帮助吗?

解决方案

由于您显然在Windows中,因此需要Windows答案。

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

@echo off
call proc1.bat
proc2

脚本将运行并设置其环境变量。两个脚本都在同一个解释器(cmd.exe实例)中运行,因此当执行prog2时,变量prog1.bat sets 设置。

不是很漂亮,但它会起作用。

(Unix人,您可以在bash脚本中执行相同的操作:“source file.sh”。)

其他提示

以下是如何在不创建包装器脚本的情况下从批处理或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)

正如你所说,进程不分享环境-因此,什么你的字面要求是不可能的,不仅在蟒蛇,但是,与任何一种编程语言。

什么你 可以 做的是把环境变量,在文件中,或在一个管道,和任

  • 有的父母进程阅读他们,并通过他们proc2前proc2是创建的,或者
  • 有proc2阅读他们,并设定它们在本地

后者需要的合作,从proc2;前者要求变成为被称之前proc2是开始。

有两点需要考虑:(1)让进程共享相同的环境,将它们以某种方式组合到同一个进程中,或者(2)让第一个进程产生包含相关环境变量的输出,这样Python就可以了阅读它并为第二个过程构建环境。我认为(虽然我不是100%肯定)没有任何方法可以像你希望的那样从子流程中获取环境。

Python标准模块多处理有一个Queues系统,允许您通过pickle要通过进程传递的对象。进程也可以使用os.pipe交换消息(pickle对象)。请记住,资源(例如:数据库连接)和句柄(例如:文件句柄)无法被腌制。

您可能会发现此链接很有趣: 多处理流程之间的通信

还有关于多处理的PyMOTw值得一提: 多处理基础知识

抱歉我的拼写

环境是从父进程继承的。在主脚本中设置所需的环境,而不是子进程(子)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top