سؤال

أرغب في استدعاء عملية عبر برنامج بايثون، لكن هذه العملية تحتاج إلى بعض متغيرات البيئة المحددة التي يتم تعيينها بواسطة عملية أخرى.كيف يمكنني الحصول على متغيرات بيئة العملية الأولى لتمريرها إلى الثانية؟

وهذا هو شكل البرنامج:

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 كبير وقبيح والثاني برنامج خاص) لذلك لا أستطيع تعديلهما (حسنًا، يمكنني استخراج كل ما أحتاجه من .bat لكنه مرهق للغاية ).

ملحوظة:أنا أستخدم نظام التشغيل Windows، ولكني أفضل الحل عبر الأنظمة الأساسية (لكن مشكلتي لن تحدث على أنظمة تشبه Unix ...)

هل كانت مفيدة؟

المحلول

ومنذ كنت على ما يبدو في ويندوز، تحتاج إجابة ويندوز.

وإنشاء ملف دفعي المجمع، على سبيل المثال. "run_program.bat"، وتشغيل كل البرامج:

@echo off
call proc1.bat
proc2

وسيتم تشغيل البرنامج النصي وتعيين متغيرات بيئتها. تشغيل كل البرامج النصية في نفس مترجم (مثيل CMD.EXE)، وبالتالي فإن المتغيرات prog1.bat مجموعات <م> سوف يتم تعيين عند تنفيذ prog2.

وليس جميلة بشكل رهيب، لكنه سوف يعمل.

و(الناس يونكس، يمكنك أن تفعل الشيء نفسه في السيناريو باش: "file.sh المصدر")

نصائح أخرى

وهنا مثال على كيف يمكنك استخراج متغيرات البيئة من ملف دفعي أو كمد دون خلق النصي المجمع. التمتع بها.

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) لديها انتاج المنتجات العملية الأولى التي تحتوي على متغيرات البيئة ذات الصلة، وبهذه الطريقة بيثون يمكن قراءتها وبناء بيئة للعملية الثانية. أعتقد (على الرغم من أنني لست متأكدا 100٪) أنه لا يوجد أي طريقة للحصول على البيئة من فرعي أو جانبي كما كنت على أمل القيام به.

وبايثون القياسية وحدة المعالجة المتعددة يكون هناك نظام قوائم الانتظار التي تسمح لك لتمرير المخلل الكائن، قادرة على أن تنتقل عن طريق العمليات. أيضا العمليات يمكن تبادل الرسائل (كائن مخلل) باستخدام os.pipe. تذكر أن الموارد (على سبيل المثال: اتصال قاعدة البيانات) والتعامل معها. (على سبيل المثال: مؤشرات الملفات) لا يمكن مخلل

وأنت قد تجد هذا الرابط للاهتمام: الاتصالات بين العمليات مع متعدد المعالجة

وأيضا PyMOTw حول متعدد المعالجة الجدير بالذكر: أساسيات المعالجة المتعددة

وآسف لبلدي هجاء

ويورث البيئة من عملية الأصل. تعيين البيئة التي تحتاج إليها في النص الرئيسي، وليس فرعي أو جانبي (طفل).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top