यहां पहले के उत्तरों पर कुछ विस्तार करने के लिए, कई विवरण हैं जिन्हें आमतौर पर अनदेखा किया जाता है।
- पसंद करते हैं
subprocess.run()अधिक subprocess.check_call()और दोस्तों से अधिक subprocess.call()से अधिक subprocess.Popen()से अधिक os.system()से अधिकos.popen()
- समझें और शायद उपयोग करें
text=True, उर्फ universal_newlines=True।
- के अर्थ को समझें
shell=Trueया shell=Falseयह कैसे बदल जाता है और शेल की उपयुक्तता की उपलब्धता।
shऔर बैश के बीच अंतर को समझें
- समझें कि एक उपप्रजाति अपने माता-पिता से कैसे अलग है, और आम तौर पर माता-पिता को नहीं बदल सकते।
- पायथन इंटरप्रेटर को पायथन के उपप्रकार के रूप में चलाने से बचें।
इन विषयों को नीचे कुछ और विस्तार से कवर किया गया है।
पसंद करते हैं subprocess.run()याsubprocess.check_call()
subprocess.Popen()समारोह एक निम्न स्तर के workhorse है लेकिन इसे सही ढंग से उपयोग करने के लिए मुश्किल है और आप प्रतिलिपि अंत / कोड के कई पंक्तियों ... जो आसानी से पहले से ही विभिन्न प्रयोजनों के लिए कार्य आवरण उच्च स्तर का एक सेट के रूप में मानक पुस्तकालय में मौजूद चिपकाने, जो निम्नलिखित में अधिक विस्तार से प्रस्तुत किए गए हैं।
यहाँ प्रलेखन से एक पैराग्राफ है :
उपप्रोसेस को लागू करने के लिए अनुशंसित दृष्टिकोण run()सभी उपयोग के मामलों के लिए फ़ंक्शन का उपयोग करना है जो इसे संभाल सकता है। अधिक उन्नत उपयोग के मामलों के लिए, अंतर्निहित Popenइंटरफ़ेस का उपयोग सीधे किया जा सकता है।
दुर्भाग्य से, इन आवरण कार्यों की उपलब्धता पायथन संस्करणों के बीच भिन्न होती है।
subprocess.run()आधिकारिक तौर पर पायथन 3.5 में पेश किया गया था। यह निम्नलिखित में से सभी को बदलने के लिए है।
subprocess.check_output()पायथन 2.7 / 3.1 में पेश किया गया था। यह मूल रूप से इसके बराबर हैsubprocess.run(..., check=True, stdout=subprocess.PIPE).stdout
subprocess.check_call()पायथन 2.5 में पेश किया गया था। यह मूल रूप से इसके बराबर हैsubprocess.run(..., check=True)
subprocess.call()मूल subprocessमॉड्यूल ( PEP-324 ) में पायथन 2.4 में पेश किया गया था । यह मूल रूप से इसके बराबर हैsubprocess.run(...).returncode
उच्च-स्तरीय एपीआई बनाम subprocess.Popen()
रिफैक्टेड और विस्तारित subprocess.run()यह पुराने विरासत के कार्यों की तुलना में अधिक तार्किक और अधिक बहुमुखी है जो इसे बदलता है। यह एक ऐसी CompletedProcessवस्तु लौटाता है जिसमें विभिन्न विधियां होती हैं जो आपको बाहर निकलने की स्थिति, मानक आउटपुट और कुछ अन्य परिणाम और समाप्त उपप्रकार से स्थिति संकेतक प्राप्त करने की अनुमति देती हैं।
subprocess.run()अगर आपको केवल पायथन पर नियंत्रण चलाने और वापस करने के लिए एक कार्यक्रम की आवश्यकता है, तो जाने का रास्ता है अधिक सम्मिलित परिदृश्यों के लिए (पृष्ठभूमि प्रक्रियाएं, संभवतया इंटरैक्टिव I / O पायथन पैरेंट प्रोग्राम के साथ) आपको अभी भी subprocess.Popen()सभी प्लंबिंग का उपयोग करने और देखभाल करने की आवश्यकता है । इसके लिए सभी गतिशील भागों की काफी जटिल समझ की आवश्यकता होती है और इसे हल्के में नहीं लिया जाना चाहिए। सरल Popenवस्तु (संभवतः अभी भी चल रही) प्रक्रिया का प्रतिनिधित्व करती है जिसे आपके कोड से उपप्रकार के शेष जीवन के लिए प्रबंधित करने की आवश्यकता होती है।
शायद इस बात पर जोर दिया जाना चाहिए कि सिर्फ subprocess.Popen()एक प्रक्रिया है। यदि आप इसे उस पर छोड़ देते हैं, तो आपके पास पायथन के साथ समवर्ती रूप से चलने वाला एक उपप्रकार है, इसलिए एक "पृष्ठभूमि" प्रक्रिया है। यदि इसे इनपुट या आउटपुट करने या अन्यथा आपके साथ समन्वय करने की आवश्यकता नहीं है, तो यह आपके पायथन प्रोग्राम के समानांतर काम कर सकता है।
से बचें os.system()औरos.popen()
अनन्त समय के बाद से (अच्छी तरह से, अजगर 2.5 के बाद से) osमॉड्यूल प्रलेखन सिफारिश करने के लिए पसंद करते हैं निहित है subprocessसे अधिक os.system():
subprocessमॉड्यूल नई प्रक्रियाओं को उत्पन्न करने और उनके परिणामों को पुन: प्राप्त करने के लिए और अधिक शक्तिशाली सुविधाएं प्रदान करता है; इस फ़ंक्शन का उपयोग करने के लिए उस मॉड्यूल का उपयोग करना बेहतर होता है।
इसके साथ समस्या system()यह है कि यह स्पष्ट रूप से प्रणाली पर निर्भर है और उपप्रकार के साथ बातचीत करने के तरीके नहीं देता है। यह केवल पायथन की पहुंच के बाहर मानक आउटपुट और मानक त्रुटि के साथ चलता है। एकमात्र जानकारी जिसे पायथन वापस प्राप्त करता है, वह कमांड की निकास स्थिति है (शून्य का अर्थ है सफलता, हालांकि गैर-शून्य मानों का अर्थ भी कुछ हद तक सिस्टम-निर्भर है)।
PEP-324 (जो पहले ही ऊपर उल्लेख किया गया था) में os.systemसमस्याग्रस्त क्यों है और subprocessउन मुद्दों को हल करने के प्रयासों के लिए एक अधिक विस्तृत तर्क शामिल है ।
os.popen()अधिक दृढ़ता से हतोत्साहित किया जाता है :
संस्करण 2.6 के बाद से पदावनत: यह फ़ंक्शन अप्रचलित है। subprocessमॉड्यूल का उपयोग करें ।
हालांकि, पायथन 3 में कुछ समय के बाद, इसे केवल उपयोग करने के लिए फिर से लागू किया गया है subprocess, और subprocess.Popen()विवरण के लिए प्रलेखन पर पुनर्निर्देशित किया गया है ।
समझें और आमतौर पर उपयोग करें check=True
आप यह भी देखेंगे कि subprocess.call()जैसी कई सीमाएँ हैं os.system()। नियमित उपयोग में, आपको आम तौर पर यह देखना चाहिए कि क्या प्रक्रिया सफलतापूर्वक समाप्त हो गई है, जो subprocess.check_call()और subprocess.check_output()(जहां बाद वाले भी समाप्त उपप्रकार के मानक उत्पादन को वापस लौटाते हैं)। इसी तरह, आप आमतौर पर इस्तेमाल करना चाहिए check=Trueके साथ subprocess.run()जब तक आप विशेष रूप से एक त्रुटि स्थिति लौटाने के लिए उपप्रक्रिया अनुमति देनी होगी।
अगर उपप्रोसेस नॉनजेरो एग्जिट स्टेटस देता है तो प्रैक्टिस के साथ check=Trueया subprocess.check_*, पायथन CalledProcessErrorअपवाद छोड़ देगा ।
उपप्रकार विफल होने पर डाउनस्ट्रीम कोड विफल होने पर एक सामान्य त्रुटि subprocess.run()को छोड़ना check=Trueऔर आश्चर्यचकित होना है।
दूसरी ओर, एक आम समस्या थी check_call()और यह check_output()था कि जिन उपयोगकर्ताओं ने इन कार्यों का नेत्रहीन उपयोग किया था, वे आश्चर्यचकित थे जब grepएक मैच नहीं मिलने पर अपवाद को उठाया गया था । (आपको संभवतः grepनीचे दिए गए अनुसार देशी पायथन कोड के साथ प्रतिस्थापित करना चाहिए ।)
गिनाई गई सभी चीजें, आपको यह समझने की जरूरत है कि शेल कमांड एक एग्जिट कोड कैसे लौटाते हैं, और किन शर्तों के तहत वे एक नॉन-जीरो (एरर) एग्जिट कोड लौटाएंगे, और एक सचेत फैसला करेंगे कि इसे कैसे हैंडल किया जाए।
समझें और शायद text=Trueउर्फ का उपयोग करेंuniversal_newlines=True
पायथन 3 के बाद से, पायथन से आंतरिक तार यूनिकोड के तार हैं। लेकिन इस बात की कोई गारंटी नहीं है कि एक सबप्रोसेस यूनिकोड आउटपुट या स्ट्रिंग्स को उत्पन्न करता है।
(यदि मतभेद तुरंत स्पष्ट नहीं हैं, तो नेड बैचेल्डर्स प्रैग्मेटिक यूनिकोड की सिफारिश की जाती है, यदि एकमुश्त अनिवार्य, पढ़ना नहीं है। लिंक के पीछे एक 36 मिनट की वीडियो प्रस्तुति है यदि आप चाहें, तो पेज को पढ़ने के बाद शायद खुद को कम समय लगेगा। )
नीचे गहरी, पायथन को एक bytesबफर लाना है और इसे किसी तरह व्याख्या करना है। यदि इसमें द्विआधारी डेटा का एक बूँद होता है, तो इसे यूनिकोड स्ट्रिंग में डिकोड नहीं किया जाना चाहिए , क्योंकि यह त्रुटि-प्रवण और बग-उत्प्रेरण व्यवहार है - ठीक उसी तरह का पेस्की व्यवहार जिसने कई पायथन 2 स्क्रिप्ट्स को पहेल किया, इससे पहले कि वहाँ एक तरीका था एन्कोडेड पाठ और बाइनरी डेटा के बीच ठीक से अंतर करना।
के साथ text=True, आप पायथन को बताते हैं कि आप वास्तव में, सिस्टम के डिफ़ॉल्ट एन्कोडिंग में पाठ डेटा की अपेक्षा करते हैं, और यह कि पायथन (यूनिकोड) स्ट्रिंग को पायथन की सर्वोत्तम क्षमता (आमतौर पर UTF-8) में किसी भी मामूली रूप से अपघटित किया जाना चाहिए शायद विंडोज को छोड़कर, तारीख प्रणाली?
यदि आप जो वापस मांगते हैं, वह नहीं है , तो पायथन सिर्फ आपको bytesतार stdoutऔर stderrतार देगा। कुछ पर हो सकता है कि बाद में बात आप करते हैं पता है कि वे पाठ स्ट्रिंग्स थे सब के बाद, और आप उनके एन्कोडिंग पता है। फिर, आप उन्हें डिकोड कर सकते हैं।
normal = subprocess.run([external, arg],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
check=True,
text=True)
print(normal.stdout)
convoluted = subprocess.run([external, arg],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
check=True)
# You have to know (or guess) the encoding
print(convoluted.stdout.decode('utf-8'))
पायथन 3.7 ने textकीवर्ड तर्क के लिए छोटे और अधिक वर्णनात्मक और समझने योग्य उपनाम पेश किया, जिसे पहले कुछ भ्रामक रूप से कहा जाता था universal_newlines।
समझे shell=Trueबनामshell=False
साथ shell=Trueआप अपने खोल के लिए एक एकल स्ट्रिंग पारित, और खोल उसे वहाँ से ले जाता है।
साथ shell=Falseआप ओएस के लिए तर्कों की सूची गुजरती हैं, खोल दरकिनार।
जब आपके पास एक शेल नहीं होता है, तो आप एक प्रक्रिया को बचाते हैं और काफी हद तक छिपी हुई जटिलता से छुटकारा पा लेते हैं , जो बग्स या यहां तक कि सुरक्षा समस्याओं को परेशान नहीं कर सकती है।
दूसरी ओर, जब आपके पास कोई शेल नहीं होता है, तो आपके पास पुनर्निर्देशन, वाइल्डकार्ड विस्तार, नौकरी पर नियंत्रण और बड़ी संख्या में अन्य शेल विशेषताएं नहीं होती हैं।
एक सामान्य गलती का उपयोग करना है shell=Trueऔर फिर भी पायथन को टोकन की सूची, या इसके विपरीत पास करना है। यह कुछ मामलों में काम करने के लिए होता है, लेकिन वास्तव में बीमार है और दिलचस्प तरीकों से टूट सकता है।
# XXX AVOID THIS BUG
buggy = subprocess.run('dig +short stackoverflow.com')
# XXX AVOID THIS BUG TOO
broken = subprocess.run(['dig', '+short', 'stackoverflow.com'],
shell=True)
# XXX DEFINITELY AVOID THIS
pathological = subprocess.run(['dig +short stackoverflow.com'],
shell=True)
correct = subprocess.run(['dig', '+short', 'stackoverflow.com'],
# Probably don't forget these, too
check=True, text=True)
# XXX Probably better avoid shell=True
# but this is nominally correct
fixed_but_fugly = subprocess.run('dig +short stackoverflow.com',
shell=True,
# Probably don't forget these, too
check=True, text=True)
सामान्य प्रतिशोध "लेकिन यह मेरे लिए काम करता है" एक उपयोगी खंडन नहीं है जब तक कि आप वास्तव में यह नहीं समझते कि यह किन परिस्थितियों में काम करना बंद कर सकता है।
उदाहरण का प्रतिपादन
बहुत बार, शेल की सुविधाओं को देशी पायथन कोड के साथ बदला जा सकता है। सिंपल अवाक या sedस्क्रिप्ट को शायद इसके बजाय केवल पायथन में अनुवाद करना चाहिए।
इसे आंशिक रूप से समझाने के लिए, यहाँ एक विशिष्ट लेकिन थोड़ा मूर्खतापूर्ण उदाहरण है जिसमें कई शैल विशेषताएं शामिल हैं।
cmd = '''while read -r x;
do ping -c 3 "$x" | grep 'round-trip min/avg/max'
done <hosts.txt'''
# Trivial but horrible
results = subprocess.run(
cmd, shell=True, universal_newlines=True, check=True)
print(results.stdout)
# Reimplement with shell=False
with open('hosts.txt') as hosts:
for host in hosts:
host = host.rstrip('\n') # drop newline
ping = subprocess.run(
['ping', '-c', '3', host],
text=True,
stdout=subprocess.PIPE,
check=True)
for line in ping.stdout.split('\n'):
if 'round-trip min/avg/max' in line:
print('{}: {}'.format(host, line))
यहाँ ध्यान देने योग्य कुछ बातें:
- साथ
shell=Falseआपको लगता है कि खोल तार के आसपास की आवश्यकता के हवाले जरूरत नहीं है। वैसे भी उद्धरण देना शायद एक त्रुटि है।
- यह अक्सर एक उपप्रकार में जितना संभव हो उतना कम कोड चलाने के लिए समझ में आता है। यह आपको अपने पायथन कोड के भीतर से निष्पादन पर अधिक नियंत्रण प्रदान करता है।
- यह कहते हुए कि, जटिल खोल पाइपलाइनें थकाऊ हैं और कभी-कभी अजगर में पुन: लागू करने के लिए चुनौतीपूर्ण हैं।
रिफलेक्टेड कोड यह भी बताता है कि शेल वास्तव में आपके लिए एक बहुत ही वाक्यविन्यास वाक्य के साथ कितना बेहतर या बदतर के लिए करता है। अजगर का कहना है स्पष्ट अंतर्निहित तुलना में बेहतर है , लेकिन अजगर कोड है बल्कि अत्यधिक शब्द और यकीनन अधिक जटिल की तुलना में यह वास्तव में है लग रहा है। दूसरी ओर, यह कई बिंदुओं की पेशकश करता है, जहां आप किसी और चीज़ के बीच में नियंत्रण को पकड़ सकते हैं, क्योंकि तुच्छता से हम बहुत आसानी से शेल कमांड आउटपुट के साथ मेजबान नाम को शामिल कर सकते हैं। (यह शेल में करने के लिए चुनौतीपूर्ण किसी भी तरह से नहीं है, या तो, लेकिन अभी तक एक और मोड़ और शायद एक और प्रक्रिया की कीमत पर।)
सामान्य शैल निर्माण
पूर्णता के लिए, यहां इन शेल विशेषताओं में से कुछ के संक्षिप्त विवरण दिए गए हैं, और कुछ नोटों पर कि वे संभवतः देशी पायथन सुविधाओं के साथ कैसे बदले जा सकते हैं।
- ग्लोबिंग उर्फ वाइल्डकार्ड विस्तार को
glob.glob()साधारण पायथन स्ट्रिंग तुलनाओं के साथ या बहुत बार बदला जा सकता है for file in os.listdir('.'): if not file.endswith('.png'): continue। बश में .{png,jpg}ब्रेस विस्तार के {1..100}साथ-साथ टिल्ड विस्तार ( ~आपके घर की निर्देशिका में विस्तार, और आम तौर पर ~accountकिसी अन्य उपयोगकर्ता की होम निर्देशिका में विस्तार) जैसी कई अन्य विस्तार सुविधाएं हैं।
- शेल वैरिएबल जैसे
$SHELLया $my_exported_varकभी-कभी केवल पायथन वैरिएबल के साथ बदले जा सकते हैं। निर्यात किए गए शेल वैरिएबल उदाहरण के रूप में उपलब्ध हैं os.environ['SHELL'](इसका अर्थ exportहै उपप्रकारों को वैरिएबल उपलब्ध कराना - एक ऐसा वैरिएबल जो उपप्रोसेस को उपलब्ध नहीं है, जाहिर तौर पर शेल के सबप्रोसेस के रूप में चलने वाले पायथन के लिए उपलब्ध नहीं होगा, या इसके विपरीत। env=कीवर्ड) subprocessविधियों का तर्क आपको उपप्रकार के वातावरण को एक शब्दकोश के रूप में परिभाषित करने की अनुमति देता है, इसलिए यह एक तरीका है कि पायथन चर को उपप्रोसेस के लिए दृश्यमान बनाया जाए)। साथ shell=Falseआप किसी भी उद्धरण निकालने का तरीका समझने की जरूरत होगी; उदाहरण के लिए, निर्देशिका नाम के आसपास के उद्धरणों के बिना cd "$HOME"समान है os.chdir(os.environ['HOME'])। (अक्सरcdवैसे भी उपयोगी या आवश्यक नहीं है, और कई शुरुआती लोग चर के आसपास दोहरे उद्धरण चिह्नों को छोड़ देते हैं और एक दिन तक इसके साथ दूर हो जाते हैं ... )
- पुनर्निर्देशन आपको अपने मानक इनपुट के रूप में एक फ़ाइल से पढ़ने की अनुमति देता है, और एक फ़ाइल के लिए अपना मानक आउटपुट लिखता है। लिखने के लिए और पढ़ने के लिए
grep 'foo' <inputfile >outputfileखुलता है , और इसकी सामग्री को मानक इनपुट के रूप में पास करता है , जिसका मानक आउटपुट तब भूमि में होता है । यह आमतौर पर मूल पायथन कोड के साथ बदलने के लिए मुश्किल नहीं है।outputfileinputfilegrepoutputfile
- पाइपलाइन पुनर्निर्देशन का एक रूप हैं।
echo foo | nlदो उपप्रकार चलाता है, जहां का मानक आउटपुट (ओएस स्तर पर, यूनिक्स की तरह सिस्टम echoमें मानक इनपुट है nl, यह एक सिंगल फाइल हैंडल है)। यदि आप पाइप लाइन के एक या दोनों छोरों को देशी पायथन कोड से नहीं बदल सकते हैं, तो शायद सभी के बाद एक शेल का उपयोग करने के बारे में सोचें, खासकर अगर पाइपलाइन की दो या तीन से अधिक प्रक्रियाएं हैं (हालांकि pipesपायथन मानक पुस्तकालय या एक नंबर में मॉड्यूल को देखें) अधिक आधुनिक और बहुमुखी तीसरे पक्ष के प्रतियोगियों)।
- नौकरी नियंत्रण आपको नौकरियों को बाधित करने, उन्हें पृष्ठभूमि में चलाने, उन्हें अग्रभूमि में वापस करने आदि की अनुमति देता है। एक प्रक्रिया को रोकने और जारी रखने के लिए मूल यूनिक्स संकेत निश्चित रूप से पायथन से उपलब्ध हैं। लेकिन नौकरी शेल में एक उच्च-स्तरीय अमूर्तता है जिसमें प्रक्रिया समूह आदि शामिल हैं जिन्हें आपको समझना होगा कि क्या आप पायथन से ऐसा कुछ करना चाहते हैं।
- जब तक आप समझते हैं कि शेल मूल रूप से एक स्ट्रिंग है, शेल में उद्धृत करना संभावित रूप से भ्रमित करना है। तो
ls -l /बराबर है, 'ls' '-l' '/'लेकिन शाब्दिक के आसपास उद्धृत पूरी तरह से वैकल्पिक है। अछूता तार जिसमें शेल मेटाचैकर होते हैं जो पैरामीटर विस्तार, व्हाट्सएप टोकन और वाइल्डकार्ड विस्तार से गुजरते हैं; डबल कोट्स व्हॉट्सएप टोकेनाइजेशन और वाइल्डकार्ड विस्तार को रोकते हैं लेकिन पैरामीटर विस्तार (चर प्रतिस्थापन, कमांड प्रतिस्थापन और बैकस्लैश प्रसंस्करण) की अनुमति देते हैं। यह सिद्धांत में सरल है, लेकिन भयावह हो सकता है, खासकर जब व्याख्या की कई परतें होती हैं (उदाहरण के लिए एक दूरस्थ शेल कमांड)।
shऔर बैश के बीच अंतर को समझें
subprocess/bin/shजब तक आप विशेष रूप से अनुरोध नहीं करते हैं तब तक अपना शेल कमांड चलाता है (विंडोज पर पाठ्यक्रम को छोड़कर, जहां यह COMSPECचर के मूल्य का उपयोग करता है )। इसका अर्थ है कि विभिन्न बैश-केवल सुविधाएँ जैसे सरणियाँ, [[आदि उपलब्ध नहीं हैं।
यदि आपको बैश-केवल सिंटैक्स का उपयोग करने की आवश्यकता है, तो आप शेल में पथ को पास कर सकते हैं executable='/bin/bash'( जैसे कि यदि आपका बैश कहीं और स्थापित है, तो आपको पथ को समायोजित करने की आवश्यकता है)।
subprocess.run('''
# This for loop syntax is Bash only
for((i=1;i<=$#;i++)); do
# Arrays are Bash-only
array[i]+=123
done''',
shell=True, check=True,
executable='/bin/bash')
A subprocessअपने माता-पिता से अलग है, और इसे बदल नहीं सकता है
कुछ सामान्य गलती कुछ ऐसा कर रही है
subprocess.run('foo=bar', shell=True)
subprocess.run('echo "$foo"', shell=True) # Doesn't work
लालित्य की कमी से हटकर "सबप्रोसेस" नाम के "उप" भाग को समझने की एक मूलभूत कमी भी है।
एक बच्चे की प्रक्रिया पायथन से पूरी तरह से अलग चलती है, और जब यह खत्म हो जाती है, तो पायथन को पता नहीं चलता कि उसने क्या किया (अस्पष्ट संकेतकों के अलावा यह बच्चे की प्रक्रिया से बाहर निकलने की स्थिति और आउटपुट से अनुमान लगा सकता है)। एक बच्चा आमतौर पर माता-पिता के वातावरण को नहीं बदल सकता है; यह एक चर सेट नहीं कर सकता, कार्यशील निर्देशिका को बदल सकता है, या, इतने सारे शब्दों में, माता-पिता से सहयोग के बिना अपने माता-पिता के साथ संवाद कर सकता है।
इस विशेष मामले में तत्काल सुधार एक ही उपप्रकार में दोनों कमांड चलाने के लिए है;
subprocess.run('foo=bar; echo "$foo"', shell=True)
हालांकि स्पष्ट रूप से इस विशेष उपयोग के मामले में शेल की आवश्यकता नहीं है। याद रखें, आप वर्तमान प्रक्रिया (और इस प्रकार इसके बच्चों) के वातावरण में फेरबदल कर सकते हैं
os.environ['foo'] = 'bar'
या के साथ एक बच्चे की प्रक्रिया के लिए एक वातावरण सेटिंग पास
subprocess.run('echo "$foo"', shell=True, env={'foo': 'bar'})
(स्पष्ट रीफैक्टरिंग का उल्लेख नहीं करना subprocess.run(['echo', 'bar']); लेकिन echoपहली जगह में एक उपप्रकार में चलाने के लिए कुछ का एक खराब उदाहरण है, निश्चित रूप से)।
पायथन से पायथन भागो मत
यह थोड़ा संदिग्ध सलाह है; निश्चित रूप से ऐसी स्थितियाँ हैं जहाँ यह समझ में आता है या पायथन इंटरप्रेटर को पायथन स्क्रिप्ट से उपप्रकार के रूप में चलाने के लिए एक परम आवश्यकता है। लेकिन बहुत बार, सही दृष्टिकोण केवल importआपके कॉलिंग स्क्रिप्ट में अन्य पायथन मॉड्यूल के लिए होता है और सीधे इसके कार्यों को कॉल करता है।
यदि अन्य पायथन स्क्रिप्ट आपके नियंत्रण में है, और यह एक मॉड्यूल नहीं है, तो इसे एक में बदलने पर विचार करें । (यह उत्तर बहुत लंबा है, इसलिए मैं यहाँ विवरण में नहीं दूंगा।)
यदि आपको समानता की आवश्यकता है, तो आप multiprocessingमॉड्यूल के साथ सबप्रोसेस में पायथन फ़ंक्शन चला सकते हैं । ऐसा भी है threadingजो एक प्रक्रिया में कई कार्य करता है (जो अधिक हल्का है और आपको अधिक नियंत्रण प्रदान करता है, लेकिन एक प्रक्रिया के भीतर उस थ्रेड में अधिक विवश भी कसकर युग्मित होते हैं, और एकल GIL से बाध्य होते हैं ।)
cwm। हो सकता है.bashrcकि आपके अंदर कुछ विन्यास हो जो इंटरएक्टिव बैश उपयोग के लिए वातावरण तैयार करता है?