Pergunta

Eu quero chamar um processo por meio de um programa de python, no entanto, este processo precisa de algumas variáveis ??de ambiente específicas que são definidas por outro processo. Como posso obter as primeiras variáveis ??de ambiente processo para passá-las para o segundo?

Isto é o que o olhar programa como:

import subprocess

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

mas o que processo não compartilham o mesmo ambiente. Note-se que estes programas não são minhas (o primeiro é grande e feio arquivo .bat eo segundo um soft proprietário) por isso não pode modificá-los (ok, eu posso extrair tudo o que eu preciso do .bat, mas é muito combersome ).

NB .: Estou usando o Windows, mas eu prefiro uma solução multi-plataforma (mas o meu problema não aconteceria em um Unix-like ...)

Foi útil?

Solução

Uma vez que você está aparentemente no Windows, você precisa de uma resposta do Windows.

Criar um arquivo de lote invólucro, por exemplo. "Run_program.bat", e executar os dois programas:

@echo off
call proc1.bat
proc2

O script será executado e definir suas variáveis ??de ambiente. Ambos os scripts são executados no mesmo intérprete (exemplo cmd.exe), então as variáveis ??prog1.bat conjuntos irá ser definido quando PROG2 é executado.

Não terrivelmente bonito, mas ele vai trabalhar.

(pessoas Unix, você pode fazer a mesma coisa em um script:. "File.sh source")

Outras dicas

Aqui está um exemplo de como você pode extrair as variáveis ??de ambiente de um lote ou arquivo cmd sem criar um script. Desfrute.

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

Assim, para responder sua pergunta, você poderia criar um arquivo .py que faz o seguinte:

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

Como você disse, os processos não compartilham o meio ambiente -. Então, o que você literalmente perguntar não é possível, não só em Python, mas com qualquer linguagem de programação

O que você pode fazer é colocar as variáveis ??de ambiente em um arquivo ou em uma tubulação, e quer

  • tem o processo pai lê-los e passá-los para proc2 antes proc2 é criado, ou
  • Have proc2 lê-los e configurá-los localmente

O último exigiria a cooperação de proc2; o primeiro requer que as variáveis ??se tornar conhecido antes proc2 é iniciado.

Duas coisas saltam à mente: (1) fazer os processos compartilham o mesmo ambiente, combinando-as de alguma forma para o mesmo processo, ou (2) ter a saída produzir o primeiro processo que contém as variáveis ??de ambiente relevantes, dessa forma Python pode lê-lo e construir o ambiente para o segundo processo. Eu acho que (embora eu não estou 100% de certeza) de que não há nenhuma maneira de obter o ambiente de um subprocesso como você está esperando para fazer.

O módulo padrão do Python multiprocessamento ter um sistema de filas que lhe permitem passar pickle objeto -able para ser passado através de processos. Também processos podem trocar mensagens (um objeto em conserva) usando os.pipe. Lembre-se que os recursos (por exemplo: conexão com o banco) e pega (por exemplo: identificadores de arquivo). Não pode ser em conserva

Você pode encontrar este link interessante: comunicação entre processos com multiprocessamento

Além disso, o PyMOTw sobre multiprocessamento vale a pena mencionar: multiprocessamento Basics

sorry for my ortografia

Ambiente é herdada do processo pai. Defina o ambiente que você precisa no script principal, não um subprocesso (criança).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top