একটি পরিবর্তিত পরিবেশ সহ পাইথন সাবপ্রসেস / পপেন


284

আমি বিশ্বাস করি যে সামান্য পরিবর্তিত পরিবেশের সাথে বাহ্যিক কমান্ড চালানো খুব সাধারণ বিষয় is আমি এটি করতে ঝোঁক:

import subprocess, os
my_env = os.environ
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)

আমি একটি অন্ত্র অনুভূতি পেয়েছি যে আরও ভাল উপায় আছে; এটা ঠিক আছে?


10
os.pathsepপ্ল্যাটফর্ম জুড়ে কাজ করে এমন পাথগুলির জন্য ":" পরিবর্তে ব্যবহার করতে পছন্দ করুন prefer দেখুন stackoverflow.com/questions/1499019/...
অমিত

8
@ ফায়েদরাস আমি নিশ্চিত নই যে তিনি যখন /usr/sbin:-) এর মতো পথগুলি ব্যবহার করছেন তখন এটি খুব প্রাসঙ্গিক
দিমিত্রি গিনজবার্গ '

উত্তর:


403

আমার মনে os.environ.copy()হয় আপনি যদি বর্তমান প্রক্রিয়াটির জন্য os.en পরিবেশ পরিবর্তন করতে চান না তবে আপনি আরও ভাল inte

import subprocess, os
my_env = os.environ.copy()
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)

>>> env = os.en वातावरण.copy >>> env ['foo'] = 'বার' ট্রেসব্যাক (অতি সাম্প্রতিক কল): ফাইল "<stdin>", লাইন 1, <মডুল> টাইপ এরর: 'উদাহরণস্বরূপ' অবজেক্ট আইটেম অ্যাসাইনমেন্ট সমর্থন করে না
ব্যবহারকারী 1338062

5
@ user1338062 আপনি প্রকৃত পদ্ধতি নির্ধারণের হয় os.environ.copyথেকে envপরিবর্তনশীল কিন্তু আপনি পদ্ধতি কলিং ফলাফল দায়িত্ব অর্পণ করা প্রয়োজনos.environ.copy() থেকে env
chown

4
পরিবেশের পরিবর্তনশীল রেজোলিউশনটি কেবলমাত্র যদি আপনি shell=Trueআপনার subprocess.Popenঅনুরোধে ব্যবহার করেন তবে কাজ করে । নোট করুন যে এটি করার সম্ভাব্যরূপে সুরক্ষা জড়িত রয়েছে।
ড্যানিয়েলপপস

সাবপ্রসেসের ভিতরে.পোপেন (আমার_কম্যান্ড, এনভিটি = মাইএনভ) - "আমার_কম্যান্ড" কী
অবিনাশ

@ভিনাশ - my_commandকেবল চালানো আদেশ। এটি উদাহরণস্বরূপ /path/to/your/own/programবা অন্য কোনও "এক্সিকিউটেবল" স্টেটমেন্ট হতে পারে ।
কাজাকিআইডি

64

বিষয়টি কী তা নির্ভর করে। যদি এটি পরিবেশকে ক্লোন এবং সংশোধন করতে হয় তবে এর একটি সমাধান হতে পারে:

subprocess.Popen(my_command, env=dict(os.environ, PATH="path"))

তবে কিছুটা নির্ভর করে যে প্রতিস্থাপিত ভেরিয়েবলগুলি বৈধ পাইথন শনাক্তকারী, যা তারা প্রায়শই হয় (আপনি কতক্ষণ পরিবেশের পরিবর্তনশীল নামগুলিতে যেগুলি বর্ণানুক্রমিক + আন্ডারস্কোর বা কোনও সংখ্যার সাথে শুরু হওয়া ভেরিয়েবল নয়?) ব্যবহার করেন।

অন্যথায় আপনি কিছু লিখতে পারেন:

subprocess.Popen(my_command, env=dict(os.environ, 
                                      **{"Not valid python name":"value"}))

খুব অদ্ভুত ক্ষেত্রে (আপনি পরিবেশের পরিবর্তনশীল নামগুলিতে নিয়ন্ত্রণ কোড বা অ-এসকিআই অক্ষরগুলি কত ঘন ঘন ব্যবহার করেন?) যে পরিবেশের কীগুলি bytesআপনি (পাইথন 3 এ) এমনকি এটি নির্মাণ করতে পারবেন না।

আপনি যেমন দেখতে পাচ্ছেন প্রযুক্তিগুলি (বিশেষত প্রথম) এখানে পরিবেশের কীগুলিতে উপকার পাওয়া যায় তা বৈধ পাইথন শনাক্তকারী এবং এটি আগে থেকেই পরিচিত (কোডিংয়ের সময়), দ্বিতীয় পদ্ধতির সমস্যা রয়েছে issues যে ক্ষেত্রে এটি নয়, আপনার সম্ভবত অন্য কোনও পদ্ধতির সন্ধান করা উচিত ।


3
ভোট দিন। আমি জানতাম না যে আপনি লিখতে পারেন dict(mapping, **kwargs)। আমি ভেবেছিলাম এটা হয় বা হয়। দ্রষ্টব্য: এটি বর্তমানে @Daniel বার্কos.environ হিসাবে গৃহীত উত্তরে প্রস্তাবিত হিসাবে এটি পরিবর্তন না করে অনুলিপি করে তবে আপনার উত্তরটি আরও সংক্ষিপ্ত হয়। পাইথন 3.5+ তে আপনি এমনকি করতে পারেন dict(**{'x': 1}, y=2, **{'z': 3})পিপ 448 দেখুন ।
jfs

1
এই উত্তরটি কিছু ভাল উপায় ব্যাখ্যা (এবং কেন এই ভাবে এত বড় নয়) নতুন এক এক দুই অভিধান একত্রীকরণ: stackoverflow.com/a/26853961/27729
krupan

@ কৃপান: এই নির্দিষ্ট ব্যবহারের ক্ষেত্রে আপনি কী অসুবিধা দেখতে পাচ্ছেন ? (স্বেচ্ছাসেবী বিভাজনগুলি মার্জ করা এবং পরিবেশের অনুলিপি / আপডেট করা বিভিন্ন কাজ)
jfs

1
@ কৃপান সব সাধারণ ক্ষেত্রে প্রথমটি হ'ল পরিবেশের ভেরিয়েবলগুলি বৈধ পাইথন শনাক্তকারী, যার অর্থ প্রথম নির্মাণ। সেক্ষেত্রে আপনার আপত্তিগুলির কোনওটিই ধারণ করে না। দ্বিতীয় ক্ষেত্রে আপনার মূল আপত্তিটি এখনও ব্যর্থ হয়েছে: নন-স্ট্রিং কীগুলি সম্পর্কে বিন্দুটি এই ক্ষেত্রে প্রযোজ্য নয় কারণ কীগুলি মূলত পরিবেশে স্ট্রিং থাকা প্রয়োজন।
মেঘ

@ জেফাসেবাস্টিয়ান আপনি সঠিক যে এই নির্দিষ্ট ক্ষেত্রে এই কৌশলটি ভাল এবং আমার নিজের আরও ভাল ব্যাখ্যা করা উচিত ছিল। আমার ক্ষমা। আমি কেবল তাদের (যেমন আমার) যারা এই কৌশলটি গ্রহণ করার প্রলোভিত হতে পারে এবং দুটি স্বেচ্ছাসেবক অভিধান মার্জ করার সাধারণ ক্ষেত্রে এটি প্রয়োগ করতে চেয়েছিল (যেটির কিছুটা আছে, আমি উত্তরটির সাথে যুক্ত উত্তর হিসাবে সংযুক্ত করেছি) সাহায্য করতে চেয়েছিলাম।
কৃপান

24

আপনি যদি কোনওভাবে আসল পরিবেশে সংজ্ঞায়িত না হয় তবে এটির my_env.get("PATH", '')পরিবর্তে এটি ব্যবহার করতে পারেন finemy_env["PATH"]PATH


20

পাইথন 3.5 এর সাহায্যে আপনি এটি এইভাবে করতে পারেন:

import os
import subprocess

my_env = {**os.environ, 'PATH': '/usr/sbin:/sbin:' + os.environ['PATH']}

subprocess.Popen(my_command, env=my_env)

এখানে আমরা একটি অনুলিপি os.environএবং ওভাররাইড দিয়ে শেষ করিPATH মান ।

এটি পিইপি 448 দ্বারা সম্ভব হয়েছিল (অতিরিক্ত আনপ্যাকিং সাধারণীকরণ) ।

আরেকটি উদাহরণ. আপনার যদি ডিফল্ট পরিবেশ (যেমন os.environ) থাকে এবং আপনি যে ডিকের সাথে ডিফল্টকে ওভাররাইড করতে চান, আপনি এটি এটি প্রকাশ করতে পারেন:

my_env = {**os.environ, **dict_with_env_variables}

@ভিনাশ, সাবপ্রোসেস দেখুন Pপপেন ডকুমেন্টেশন। এটি "প্রোগ্রাম আর্গুমেন্টের ক্রম বা অন্যথায় একটি একক স্ট্রিং"।
স্কভোরোডকিন

10

Os.envrion অবজেক্ট ইত্যাদি অনুলিপি না করে অস্থায়ীভাবে পরিবেশের পরিবর্তনশীল সেট করতে, আমি এটি করি:

process = subprocess.Popen(['env', 'RSYNC_PASSWORD=foobar', 'rsync', \
'rsync://username@foobar.com::'], stdout=subprocess.PIPE)

4

Env পরামিতি একটি অভিধান গ্রহণ করে। আপনি কেবল os.en वातावरण নিতে পারেন, এতে একটি কী (আপনার পছন্দসই ভেরিয়েবল) যুক্ত করতে পারেন (আপনার প্রয়োজন হলে ডিকের অনুলিপিটিতে) এবং এটি প্যারামিটার হিসাবে ব্যবহার করতে পারেন Popen


আপনি যদি নতুন পরিবেশের পরিবর্তনশীল যুক্ত করতে চান তবে এটি সবচেয়ে সহজ উত্তর। os.environ['SOMEVAR'] = 'SOMEVAL'
অ্যান্ডি ফ্রেলে

1

আমি জানি এটির কিছু সময়ের জন্য জবাব দেওয়া হয়েছে, তবে কিছু পয়েন্ট রয়েছে যা কিছু তাদের পরিবেশ পরিবর্তনশীলগুলিতে পাঠের পরিবর্তে পাইথনপথ ব্যবহার সম্পর্কে জানতে চাইতে পারে। আমি ক্রোনজবস দিয়ে পাইথন স্ক্রিপ্টগুলি চালনার ব্যাখ্যাটির রূপরেখা করেছি যা পরিবর্তিত পরিবেশের সাথে অন্যভাবে আচরণ করে ( এখানে পাওয়া গেছে )। ভেবেছিলাম তাদের পক্ষে কিছুটা ভাল হবে যারা আমার মতো এই উত্তর সরবরাহ করা থেকে কিছুটা বেশি প্রয়োজন।


0

নির্দিষ্ট পরিস্থিতিতে আপনি কেবলমাত্র আপনার সাব-প্রসেসের প্রয়োজনীয়তার জন্য পরিবেশের পরিবর্তনগুলি সরাতে চাইতে পারেন, তবে আমি মনে করি আপনি সাধারণভাবে সঠিক ধারণা পেয়েছেন (এটি আমিও এটিই করি)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.