문제

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 파일이고 두 번째는 독점적 인 소프트)를 수정할 수 없습니다 (OK, .BAT에서 필요한 모든 것을 추출 할 수는 있지만 매우 편안합니다. ).

NB : Windows를 사용하고 있지만 크로스 플랫폼 솔루션을 선호합니다 (그러나 내 문제는 Unix와 같은 경우에는 발생하지 않을 것입니다 ...)

도움이 되었습니까?

해결책

분명히 창에 있으므로 Windows 답변이 필요합니다.

래퍼 배치 파일을 만듭니다. "run_program.bat"및 두 프로그램을 모두 실행합니다.

@echo off
call proc1.bat
proc2

스크립트가 실행되고 환경 변수를 설정합니다. 두 스크립트는 동일한 통역사 (cmd.exe 인스턴스)에서 실행되므로 변수는 prog1.bat sets입니다. ~ 할 것이다 Prog2가 실행될 때 설정해야합니다.

크게 예쁘지는 않지만 효과가 있습니다.

(Unix People, 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% 확실하지는 않지만).

파이썬 표준 모듈 다중 프로세싱 피클 가능한 물체를 전달하여 프로세스를 통과 할 수있는 대기열 시스템이 있어야합니다. 또한 프로세스는 os.pipe를 사용하여 메시지 (절인 객체)를 교환 할 수 있습니다. 리소스 (예 : 데이터베이스 연결) 및 핸들 (예 : 파일 핸들)은 절인 할 수 없습니다.

이 링크가 흥미로울 수 있습니다.멀티 프로세싱을 통한 프로세스 간의 통신

또한 언급 할 가치가있는 멀티 프로세싱에 대한 pymotw :다중 프로세싱 기본

내 철자에 대해 죄송합니다

환경은 부모 프로세스에서 상속됩니다. 하위 프로세스가 아닌 기본 스크립트에서 필요한 환경을 설정하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top