आप पायथन स्क्रिप्ट के भीतर से एक बाहरी कमांड (जैसे कि मैं इसे यूनिक्स शेल या विंडोज कमांड प्रॉम्प्ट पर टाइप क्यों करूंगा) को कॉल करता हूं?
आप पायथन स्क्रिप्ट के भीतर से एक बाहरी कमांड (जैसे कि मैं इसे यूनिक्स शेल या विंडोज कमांड प्रॉम्प्ट पर टाइप क्यों करूंगा) को कॉल करता हूं?
जवाबों:
को देखो उपप्रक्रिया मानक पुस्तकालय में मॉड्यूल:
import subprocess
subprocess.run(["ls", "-l"])
का लाभ subprocess
बनाम system
है कि यह अधिक लचीला है (आप प्राप्त कर सकते हैं stdout
, stderr
, "असली" स्थिति कोड, बेहतर त्रुटि हैंडलिंग, आदि ...)।
आधिकारिक दस्तावेज की सिफारिश की subprocess
वैकल्पिक से अधिक मॉड्यूल os.system()
:
subprocess
मॉड्यूल नई प्रक्रियाओं को उत्पन्न करने और उनके परिणामों को पुन: प्राप्त करने के लिए और अधिक शक्तिशाली सुविधाएं प्रदान करता है; इस फ़ंक्शन का उपयोग करने के लिए उस मॉड्यूल का उपयोग करना बेहतर है [os.system()
]।
उपप्रक्रिया मॉड्यूल के साथ की जगह पुराने कार्य में अनुभाग subprocess
प्रलेखन कुछ उपयोगी व्यंजनों हो सकता है।
3.5 से पहले पायथन के संस्करणों के लिए, उपयोग करें call
:
import subprocess
subprocess.call(["ls", "-l"])
shell=True
काम करने के लिए आपको इसका उपयोग करना होगा।
shell=True
, इस उद्देश्य के लिए अजगर os.path.expandvars के साथ आता है । आपके मामले में आप लिख सकते हैं os.path.expandvars("$PATH")
:। @SethMMorton कृपया अपनी टिप्पणी पर पुनर्विचार करें -> शैल का उपयोग क्यों नहीं करना है = सही
for
लूप में कई कमांड चलाना चाहता हूं तो मैं इसे कैसे करूं बिना इसे मेरी पाइथन स्क्रिप्ट को ब्लॉक किए? मैं उस कमांड के आउटपुट के बारे में परवाह नहीं करता, जिसे मैं उनमें से बहुत से चलाना चाहता हूं।
subprocess
जब shell=False
, तो का उपयोग shlex.split
यह करने के लिए एक आसान तरीका के लिए docs.python.org/2/library/shlex.html#shlex.split
यहां बाहरी कार्यक्रमों और प्रत्येक के फायदे और नुकसान को कॉल करने के तरीकों का सारांश दिया गया है:
os.system("some_command with args")
आपके सिस्टम के शेल में कमांड और दलीलें पास करता है। यह अच्छा है क्योंकि आप वास्तव में इस तरीके से एक साथ कई कमांड चला सकते हैं और पाइप और इनपुट / आउटपुट पुनर्निर्देशन सेट कर सकते हैं। उदाहरण के लिए:
os.system("some_command < input_file | another_command > output_file")
हालाँकि, जब यह सुविधाजनक होता है, तो आपको मैन्युअल रूप से शेल वर्णों जैसे रिक्त स्थान इत्यादि से बचना होगा, दूसरी ओर, यह आपको कमांड चलाने की भी सुविधा देता है, जो केवल शेल कमांड हैं और वास्तव में बाहरी प्रोग्राम नहीं। दस्तावेज देखें ।
stream = os.popen("some_command with args")
के रूप में एक ही काम करेंगे os.system
कि यह आपको एक फ़ाइल जैसी वस्तु देता है जिसे आप मानक इनपुट / आउटपुट का उपयोग करने के लिए उपयोग कर सकते हैं। पोपेन के 3 अन्य संस्करण हैं जो सभी i / o को थोड़ा अलग तरीके से संभालते हैं। यदि आप एक स्ट्रिंग के रूप में सब कुछ पास करते हैं, तो आपका कमांड शेल में पारित हो जाता है; यदि आप उन्हें एक सूची के रूप में पास करते हैं तो आपको कुछ भी बचने की चिंता करने की आवश्यकता नहीं है। दस्तावेज देखें ।
मॉड्यूल की Popen
श्रेणी subprocess
। यह एक प्रतिस्थापन के रूप में अभिप्रेत है, os.popen
लेकिन इतना व्यापक होने के कारण थोड़ा अधिक जटिल होने का नकारात्मक पक्ष है। उदाहरण के लिए, आप कहेंगे:
print subprocess.Popen("echo Hello World", shell=True, stdout=subprocess.PIPE).stdout.read()
के बजाय:
print os.popen("echo Hello World").read()
लेकिन 4 अलग-अलग पॉपेन फ़ंक्शंस के बजाय एक एकीकृत कक्षा में सभी विकल्पों का होना अच्छा है। दस्तावेज देखें ।
call
से समारोह subprocess
मॉड्यूल। यह मूल रूप से Popen
कक्षा की तरह ही है और सभी समान तर्क देता है, लेकिन यह तब तक इंतजार करता है जब तक कि कमांड पूरा नहीं हो जाता है और आपको रिटर्न कोड देता है। उदाहरण के लिए:
return_code = subprocess.call("echo Hello World", shell=True)
दस्तावेज देखें ।
यदि आप पायथन 3.5 या उसके बाद के हैं, तो आप नए subprocess.run
फ़ंक्शन का उपयोग कर सकते हैं , जो ऊपर की तरह बहुत अधिक है, लेकिन इससे भी अधिक लचीला है और एक CompletedProcess
ऑब्जेक्ट को तब वापस करता है जब कमांड निष्पादित करता है।
ओएस मॉड्यूल में सभी कांटे / निष्पादन / स्पॉन फ़ंक्शंस हैं जो आपके पास सी प्रोग्राम में होंगे, लेकिन मैं उन्हें सीधे उपयोग करने की सलाह नहीं देता।
subprocess
मॉड्यूल शायद होना चाहिए कि तुम क्या प्रयोग करते हैं।
अंत में कृपया ध्यान रखें कि सभी तरीकों के लिए जहां आप एक स्ट्रिंग के रूप में शेल द्वारा निष्पादित होने के लिए अंतिम कमांड पास करते हैं और आप इसे से बचने के लिए जिम्मेदार हैं। यदि आपके द्वारा पास किए जाने वाले स्ट्रिंग के किसी भी हिस्से पर पूरी तरह से भरोसा नहीं किया जा सकता है, तो गंभीर सुरक्षा निहितार्थ हैं । उदाहरण के लिए, यदि कोई उपयोगकर्ता स्ट्रिंग के कुछ / किसी भी हिस्से में प्रवेश कर रहा है। यदि आप अनिश्चित हैं, तो केवल स्थिरांक के साथ इन विधियों का उपयोग करें। आपको संकेत देने का संकेत देने के लिए इस कोड पर विचार करें:
print subprocess.Popen("echo %s " % user_input, stdout=PIPE).stdout.read()
और कल्पना करें कि उपयोगकर्ता कुछ ऐसा करता है "मेरे मामा ने मुझे प्यार नहीं किया और & rm -rf /" जो पूरे फाइल सिस्टम को मिटा सकता है।
open
।
subprocess.run()
। docs.python.org/3.5/library/subprocess.html#subprocess.run
subprocess.run(..)
वास्तव में क्या करता है "यह डिफ़ॉल्ट रूप से stdout या stderr पर कब्जा नहीं करता है।" मतलब? subprocess.check_output(..)
एसटीडीआरआर के बारे में क्या ?
echo
पास किए गए स्ट्रिंग के सामने सूचना Popen
? तो पूरा कमांड होगा echo my mama didnt love me && rm -rf /
।
subprocess.run()
अपने पुराने भाई-बहनों की जरूरत होती है subprocess.check_call()
। ऐसे मामलों के लिए जहां ये पर्याप्त नहीं हैं, देखें subprocess.Popen()
। os.popen()
शायद बिल्कुल भी उल्लेख नहीं किया जाना चाहिए, या "अपना खुद का कांटा / निष्पादन / स्पॉन कोड हैक करने" के बाद भी आना चाहिए।
विशिष्ट कार्यान्वयन:
import subprocess
p = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout.readlines():
print line,
retval = p.wait()
आप stdout
पाइप में डेटा के साथ जो करना चाहते हैं करने के लिए स्वतंत्र हैं । वास्तव में, आप बस उन मापदंडों ( stdout=
और stderr=
) को छोड़ सकते हैं और यह व्यवहार करेंगे os.system()
।
.readlines()
एक ही बार में सभी लाइनों को पढ़ता है , यह तब तक अवरुद्ध होता है जब तक कि उपप्रकार बाहर नहीं निकलता (पाइप के अपने छोर को बंद कर देता है)। वास्तविक समय में पढ़ने के लिए (यदि कोई बफरिंग मुद्दों है वहाँ) आप:for line in iter(p.stdout.readline, ''): print line,
p.stdout.readline()
(ध्यान दें: s
अंत में कोई भी) कोई भी डेटा तब तक नहीं देखेगा जब तक कि बच्चा अपने बफर को नहीं भरता। यदि बच्चा ज्यादा डेटा नहीं पैदा करता है, तो आउटपुट वास्तविक समय में नहीं होगा। क्यू में दूसरा कारण देखें : बस एक पाइप (पॉपेन ()) का उपयोग क्यों न करें? । इस जवाब में कुछ वर्कअराउंड्स दिए गए हैं (pexpect, pty, stdbuf)
Popen
सरल कार्यों के लिए अनुशंसा नहीं करनी चाहिए । यह भी अनावश्यक रूप से निर्दिष्ट करता है shell=True
। किसी एक subprocess.run()
उत्तर की कोशिश करो ।
कुछ को कॉलिंग से बच्चे की प्रक्रिया को अलग करने पर संकेत मिलता है (पृष्ठभूमि में बच्चे की प्रक्रिया शुरू करना)।
मान लीजिए आप एक CGI स्क्रिप्ट से एक लंबा काम शुरू करना चाहते हैं। यही है, बच्चे की प्रक्रिया CGI स्क्रिप्ट निष्पादन प्रक्रिया से अधिक समय तक जीवित रहना चाहिए।
सबप्रोसेस मॉड्यूल प्रलेखन से शास्त्रीय उदाहरण है:
import subprocess
import sys
# Some code here
pid = subprocess.Popen([sys.executable, "longtask.py"]) # Call subprocess
# Some more code here
यहाँ विचार यह है कि आप 'कॉल उपप्रकार' की प्रतीक्षा नहीं करना चाहते हैं जब तक कि longtask.py समाप्त न हो जाए। लेकिन यह स्पष्ट नहीं है कि उदाहरण के बाद लाइन 'कुछ और कोड' के बाद क्या होता है।
मेरा लक्ष्य प्लेटफ़ॉर्म FreeBSD था, लेकिन विकास विंडोज पर था, इसलिए मुझे पहले विंडोज पर समस्या का सामना करना पड़ा।
विंडोज (विंडोज एक्सपी) पर, पैरेंट प्रोसेस तब तक खत्म नहीं होगा जब तक कि लॉन्गटैस्टकैम ने अपना काम खत्म नहीं कर दिया है। यह वह नहीं है जो आप सीजीआई स्क्रिप्ट में चाहते हैं। समस्या पायथन के लिए विशिष्ट नहीं है; PHP समुदाय में समस्याएं समान हैं।
इसका समाधान Windows API में अंतर्निहित CreateProcess फंक्शन से DETACHED_PROCESS प्रोसेस क्रिएशन फ्लैग को पास करना है। यदि आपके पास pywin32 स्थापित है, तो आप ध्वज को win32process मॉड्यूल से आयात कर सकते हैं, अन्यथा आपको इसे स्वयं परिभाषित करना चाहिए:
DETACHED_PROCESS = 0x00000008
pid = subprocess.Popen([sys.executable, "longtask.py"],
creationflags=DETACHED_PROCESS).pid
/ * उत्तर प्रदेश २०१५.१०.२ @ नोटों के नीचे एक टिप्पणी में @eryksun, कि शब्दार्थ सही झंडा है CREATE_NEW_CONSOLE (0x00000010) * /
FreeBSD में हमें एक और समस्या है: जब मूल प्रक्रिया समाप्त हो जाती है, तो यह बच्चे की प्रक्रियाओं को भी समाप्त कर देती है। और यह वह नहीं है जो आप सीजीआई स्क्रिप्ट में चाहते हैं। कुछ प्रयोगों से पता चला कि समस्या sys.stdout को साझा करने में लग रही थी। और कार्य समाधान निम्नलिखित था:
pid = subprocess.Popen([sys.executable, "longtask.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
मैंने अन्य प्लेटफार्मों पर कोड की जांच नहीं की है और FreeBSD पर व्यवहार के कारणों को नहीं जानता है। अगर किसी को पता है, तो कृपया अपने विचार साझा करें। पाइथन में पृष्ठभूमि की प्रक्रिया शुरू करने पर गुगली करने से अभी तक कोई रोशनी नहीं निकलती है।
DETACHED_PROCESS
में creationflags
विरासत में या एक सांत्वना बनाने से बच्चे को रोकने के द्वारा टाल इस। यदि आप इसके बजाय एक नया कंसोल चाहते हैं, तो CREATE_NEW_CONSOLE
(0x00000010) का उपयोग करें ।
os.devnull
कुछ कंसोल प्रोग्रामों को मानक हैंडल सेट करने की आवश्यकता हो सकती है क्योंकि एक त्रुटि के साथ बाहर निकलता है अन्यथा। जब आप चाहते हैं कि बच्चे की प्रक्रिया को पेरेंट प्रक्रिया के साथ उपयोगकर्ता के साथ बातचीत करने के लिए एक नया कंसोल बनाएं। यह दोनों को एक ही विंडो में करने की कोशिश करना भ्रामक होगा।
import os
os.system("your command")
ध्यान दें कि यह खतरनाक है, क्योंकि कमांड को साफ नहीं किया गया है। मैं इसे 'os' और 'sys' मॉड्यूल पर संबंधित दस्तावेज के लिए Google पर छोड़ता हूं। कार्यों का एक गुच्छा (निष्पादन * और स्पॉन *) हैं जो समान कार्य करेंगे।
subprocess
थोड़ा और अधिक बहुमुखी और पोर्टेबल समाधान के रूप में इंगित करना चाहिए । बाहरी कमांड चलाना बेशक स्वाभाविक है (आपको यह सुनिश्चित करना होगा कि प्रत्येक आर्किटेक्चर पर कमांड उपलब्ध है जिसे आपको समर्थन करने की आवश्यकता है) और उपयोगकर्ता इनपुट को एक बाहरी कमांड के रूप में पास करना स्वाभाविक रूप से असुरक्षित है।
मैं का उपयोग कर की सलाह देते हैं उपप्रक्रिया os.system बजाय मॉड्यूल क्योंकि यह आप के लिए भागने शेल और इसलिए ज्यादा सुरक्षित है करता है।
subprocess.call(['ping', 'localhost'])
subprocess
है जब shell=False
, तो का उपयोग shlex.split
यह करने के लिए एक आसान तरीका के लिए docs.python.org/2/library/shlex.html#shlex.split ( डॉक्स डॉक्सहोमथोन.org/2/library/subprocess.html#popen-constructor ) के अनुसार यह अनुशंसित तरीका है
import os
cmd = 'ls -al'
os.system(cmd)
यदि आप कमांड के परिणाम वापस करना चाहते हैं, तो आप उपयोग कर सकते हैं os.popen
। हालाँकि, यह उपप्रकार मॉड्यूल के पक्ष में संस्करण 2.6 के बाद से हटा दिया गया है , जिसे अन्य उत्तरों ने अच्छी तरह से कवर किया है।
बहुत सारे विभिन्न पुस्तकालय हैं जो आपको पायथन के साथ बाहरी कमांड को कॉल करने की अनुमति देते हैं। प्रत्येक लाइब्रेरी के लिए मैंने एक विवरण दिया है और एक बाहरी कमांड को कॉल करने का एक उदाहरण दिखाया है। उदाहरण के रूप में मैंने जो कमांड का उपयोग किया है ls -l
(सभी फ़ाइलों की सूची)। यदि आप उन सभी पुस्तकालयों के बारे में अधिक जानकारी प्राप्त करना चाहते हैं जिन्हें मैंने सूचीबद्ध किया है और उनमें से प्रत्येक के लिए दस्तावेज़ीकरण जुड़ा हुआ है।
सूत्रों का कहना है:
ये सभी पुस्तकालय हैं:
उम्मीद है कि यह आपको किस पुस्तकालय का उपयोग करने पर निर्णय लेने में मदद करेगा :)
उपप्रक्रिया
सबप्रोसेस आपको बाहरी कमांड को कॉल करने और उनके इनपुट / आउटपुट / त्रुटि पाइप (स्टड, स्टडआउट, और स्टडर) से कनेक्ट करने की अनुमति देता है। सबप्रोसेस कमांड चलाने के लिए डिफ़ॉल्ट विकल्प है, लेकिन कभी-कभी अन्य मॉड्यूल बेहतर होते हैं।
subprocess.run(["ls", "-l"]) # Run command
subprocess.run(["ls", "-l"], stdout=subprocess.PIPE) # This will run the command and return any output
subprocess.run(shlex.split("ls -l")) # You can also use the shlex library to split the command
ओएस
ओएस का उपयोग "ऑपरेटिंग सिस्टम निर्भर कार्यक्षमता" के लिए किया जाता है। इसका उपयोग बाहरी आदेशों को कॉल करने के लिए भी किया जा सकता है os.system
और os.popen
(नोट: एक उपप्रकार भी है। पोपेन)। ओएस हमेशा शेल चलाएगा और उन लोगों के लिए एक सरल विकल्प है जिन्हें उपयोग करने की आवश्यकता नहीं है, या नहीं जानते हैं subprocess.run
।
os.system("ls -l") # run command
os.popen("ls -l").read() # This will run the command and return any output
श
श एक सबप्रोसेस इंटरफ़ेस है जो आपको प्रोग्राम को कॉल करने देता है जैसे कि वे फ़ंक्शन थे। यदि आप कई बार कमांड चलाना चाहते हैं तो यह उपयोगी है।
sh.ls("-l") # Run command normally
ls_cmd = sh.Command("ls") # Save command as a variable
ls_cmd() # Run command as if it were a function
सीसा
साहुल "लिपि-जैसा" पायथन कार्यक्रमों के लिए एक पुस्तकालय है। आप प्रोग्राम को फंक्शन जैसे कह सकते हैं sh
। यदि आप शेल के बिना पाइपलाइन चलाना चाहते हैं तो प्लंबम उपयोगी है।
ls_cmd = plumbum.local("ls -l") # get command
ls_cmd() # run command
pexpect
pexpect आपको बाल अनुप्रयोगों को स्पॉन करने देता है, उन्हें नियंत्रित करता है और उनके आउटपुट में पैटर्न ढूंढता है। यह उन आदेशों के लिए उपप्रकार का एक बेहतर विकल्प है जो यूनिक्स पर एक ट्टी की उम्मीद करते हैं।
pexpect.run("ls -l") # Run command as normal
child = pexpect.spawn('scp foo user@example.com:.') # Spawns child application
child.expect('Password:') # When this is the output
child.sendline('mypassword')
कपड़ा
कपड़े एक पायथन 2.5 और 2.7 पुस्तकालय है। यह आपको स्थानीय और दूरस्थ शेल कमांड निष्पादित करने की अनुमति देता है। सुरक्षित शेल (SSH) में कमांड चलाने के लिए फैब्रिक सरल विकल्प है
fabric.operations.local('ls -l') # Run command as normal
fabric.operations.local('ls -l', capture = True) # Run command and receive output
दूत
दूत को "मनुष्यों के लिए उपप्रकार" के रूप में जाना जाता है। इसका उपयोग subprocess
मॉड्यूल के चारों ओर एक सुविधा आवरण के रूप में किया जाता है ।
r = envoy.run("ls -l") # Run command
r.std_out # get output
आदेशों
commands
के लिए आवरण कार्य शामिल हैं os.popen
, लेकिन इसे पायथन 3 से हटा दिया गया है क्योंकि subprocess
यह एक बेहतर विकल्प है।
एडिट जेएफ सेबेस्टियन की टिप्पणी पर आधारित था।
मैं हमेशा fabric
इस तरह की चीजों के लिए उपयोग करता हूं :
from fabric.operations import local
result = local('ls', capture=True)
print "Content:/n%s" % (result, )
लेकिन यह एक अच्छा उपकरण लगता है: sh
(पायथन सबप्रोसेस इंटरफ़ेस) ।
एक उदाहरण देखें:
from sh import vgdisplay
print vgdisplay()
print vgdisplay('-v')
print vgdisplay(v=True)
"Pexpect" पायथन लाइब्रेरी की भी जाँच करें।
यह बाहरी कार्यक्रमों / आदेशों, यहां तक कि ssh, ftp, telnet, आदि के संवादात्मक नियंत्रण के लिए अनुमति देता है। आप बस कुछ टाइप कर सकते हैं:
child = pexpect.spawn('ftp 192.168.0.24')
child.expect('(?i)name .*: ')
child.sendline('anonymous')
child.expect('(?i)password')
सबप्रोसेस मॉड्यूल (पायथन 3) का उपयोग करें :
import subprocess
subprocess.run(['ls', '-l'])
यह अनुशंसित मानक तरीका है। हालांकि, अधिक जटिल कार्य (पाइप, आउटपुट, इनपुट, आदि) निर्माण और लिखने के लिए थकाऊ हो सकते हैं।
पायथन संस्करण पर ध्यान दें: यदि आप अभी भी पायथन 2 का उपयोग कर रहे हैं, तो subprocess.call समान तरीके से काम करता है।
Protip: shlex.split आप के लिए आदेश पार्स करने के लिए मदद कर सकते हैं run
, call
और अन्य subprocess
मामले में कार्यों आप नहीं करना चाहते हैं (या नहीं कर सकती!) सूचियों के रूप में उन्हें प्रदान करते हैं:
import shlex
import subprocess
subprocess.run(shlex.split('ls -l'))
यदि आपको बाहरी निर्भरता से ऐतराज नहीं है, तो प्लम्बम का उपयोग करें :
from plumbum.cmd import ifconfig
print(ifconfig['wlan0']())
यह सबसे अच्छा subprocess
आवरण है। यह क्रॉस-प्लेटफ़ॉर्म है, अर्थात यह विंडोज और यूनिक्स जैसी प्रणालियों पर काम करता है। द्वारा स्थापित करें pip install plumbum
।
एक और लोकप्रिय पुस्तकालय श :
from sh import ifconfig
print(ifconfig('wlan0'))
हालाँकि, sh
विंडोज समर्थन को गिरा दिया, इसलिए यह उतना भयानक नहीं है जितना पहले हुआ करता था। द्वारा स्थापित करें pip install sh
।
यदि आपको उस कमांड से आउटपुट की आवश्यकता है जिसे आप कॉल कर रहे हैं, तो आप subprocess.check_output (पायथन 2.7+) का उपयोग कर सकते हैं ।
>>> subprocess.check_output(["ls", "-l", "/dev/null"])
'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
शेल पैरामीटर पर भी ध्यान दें ।
यदि शेल है
True
, तो शेल के माध्यम से निर्दिष्ट कमांड निष्पादित किया जाएगा। यह उपयोगी हो सकता है यदि आप मुख्य रूप से पायथन का उपयोग कर रहे हैं, जो कि अधिकांश सिस्टम शेलों पर प्रदान किए गए बढ़ाया नियंत्रण प्रवाह के लिए है और फिर भी शेल के पाइप, फ़ाइल नाम वाइल्डकार्ड, पर्यावरण चर विस्तार, और ~ एक घर के घर के विस्तार जैसे अन्य शेल सुविधाओं के लिए सुविधाजनक पहुंच चाहते हैं। निर्देशिका। हालांकि, ध्यान दें कि अजगर खुद के कार्यान्वयन प्रदान करता है कई खोल जैसी सुविधाओं (विशेष रूप से,glob
,fnmatch
,os.walk()
,os.path.expandvars()
,os.path.expanduser()
, औरshutil
)।
check_output
एक स्ट्रिंग के बजाय एक सूची की आवश्यकता है। यदि आप अपने कॉल को वैध बनाने के लिए उद्धृत स्थानों पर भरोसा नहीं करते हैं, तो ऐसा करने का सबसे सरल, सबसे पठनीय तरीका है subprocess.check_output("ls -l /dev/null".split())
।
इसी तरह मैं अपनी आज्ञा चलाता हूं। इस कोड में वह सब कुछ है जिसकी आपको बहुत आवश्यकता है
from subprocess import Popen, PIPE
cmd = "ls -l ~/"
p = Popen(cmd , shell=True, stdout=PIPE, stderr=PIPE)
out, err = p.communicate()
print "Return code: ", p.returncode
print out.rstrip(), err.rstrip()
subprocess.run
यदि आपके कोड को पहले पायथन संस्करणों के साथ संगतता बनाए रखने की आवश्यकता नहीं है, तो Python 3.5 के रूप में अनुशंसित दृष्टिकोण है । यह अधिक सुसंगत है और एनवॉय के समान ही उपयोग में आसानी प्रदान करता है। (हालांकि पाइपिंग उतना सीधा नहीं है। इस सवाल को कैसे देखें ।)
दस्तावेज से कुछ उदाहरण यहां दिए गए हैं ।
एक प्रक्रिया चलाएँ:
>>> subprocess.run(["ls", "-l"]) # Doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)
असफल रन पर उठाएँ:
>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
कैप्चर आउटपुट:
>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')
मैं दूत की कोशिश करने की सलाह देता हूं । यह सबप्रोसेस के लिए एक आवरण है, जो पुराने मॉड्यूल और कार्यों को बदलने का लक्ष्य रखता है । दूत मनुष्यों के लिए उपप्रकार है।
README से उदाहरण का उपयोग :
>>> r = envoy.run('git config', data='data to pipe in', timeout=2)
>>> r.status_code
129
>>> r.std_out
'usage: git config [options]'
>>> r.std_err
''
चारों ओर पाइप सामान:
>>> r = envoy.run('uptime | pbcopy')
>>> r.command
'pbcopy'
>>> r.status_code
0
>>> r.history
[<Response 'uptime'>]
पायथन में एक बाहरी कमांड को कॉल करना
सरल, उपयोग subprocess.run
, जो एक CompletedProcess
वस्तु लौटाता है :
>>> import subprocess
>>> completed_process = subprocess.run('python --version')
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
>>> completed_process
CompletedProcess(args='python --version', returncode=0)
अजगर 3.5 के रूप में, प्रलेखन की सिफारिश की subprocess.run :
सबप्रोसेस को लागू करने के लिए अनुशंसित दृष्टिकोण सभी उपयोग के मामलों के लिए रन () फ़ंक्शन का उपयोग करना है जो इसे संभाल सकता है। अधिक उन्नत उपयोग के मामलों के लिए, अंतर्निहित पॉपेन इंटरफ़ेस का सीधे उपयोग किया जा सकता है।
यहाँ सबसे सरल संभव उपयोग का एक उदाहरण है - और यह बिल्कुल वैसा ही है जैसा कि पूछा गया है:
>>> import subprocess
>>> completed_process = subprocess.run('python --version')
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
>>> completed_process
CompletedProcess(args='python --version', returncode=0)
run
आदेश को सफलतापूर्वक समाप्त करने के लिए प्रतीक्षा करता है, फिर एक CompletedProcess
वस्तु लौटाता है । यह इसके बजाय बढ़ा सकता है TimeoutExpired
(यदि आप इसे timeout=
तर्क देते हैं) या CalledProcessError
(यदि यह विफल रहता है और आप पास हो जाते हैं check=True
)।
जैसा कि आप ऊपर के उदाहरण से समझ सकते हैं, stdout और stderr दोनों ही अपने-अपने stdout और stderr को डिफ़ॉल्ट रूप से पाइप करते हैं।
हम लौटी हुई वस्तु का निरीक्षण कर सकते हैं और दिए गए कमांड को देख सकते हैं और रिटर्नकोड:
>>> completed_process.args
'python --version'
>>> completed_process.returncode
0
यदि आप आउटपुट कैप्चर करना चाहते हैं, तो आप subprocess.PIPE
उपयुक्त stderr
या पास कर सकते हैं stdout
:
>>> cp = subprocess.run('python --version',
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
>>> cp.stderr
b'Python 3.6.1 :: Anaconda 4.4.0 (64-bit)\r\n'
>>> cp.stdout
b''
(मुझे यह दिलचस्प और थोड़ा उलझा हुआ लगता है कि संस्करण की जानकारी स्टडआउट के बजाय स्टडर को मिल जाती है।)
प्रोग्राम से निर्मित स्ट्रिंग प्रदान करने के लिए कोई व्यक्ति आसानी से कमांड स्ट्रिंग प्रदान कर सकता है (जैसे प्रश्न बताता है)। प्रोग्रामिंग स्ट्रिंग्स का निर्माण न करें। यह एक संभावित सुरक्षा मुद्दा है। यह मान लेना बेहतर है कि आपको इनपुट पर भरोसा नहीं है।
>>> import textwrap
>>> args = ['python', textwrap.__file__]
>>> cp = subprocess.run(args, stdout=subprocess.PIPE)
>>> cp.stdout
b'Hello there.\r\n This is indented.\r\n'
ध्यान दें, केवल args
स्थिति को पारित किया जाना चाहिए।
यहाँ स्रोत में वास्तविक हस्ताक्षर है और जैसा कि दिखाया गया है help(run)
:
def run(*popenargs, input=None, timeout=None, check=False, **kwargs):
popenargs
और kwargs
करने के लिए दिया जाता है Popen
निर्माता। input
बाइट्स की एक स्ट्रिंग हो सकती है (या यूनिकोड, यदि एन्कोडिंग निर्दिष्ट करें या universal_newlines=True
) जो कि सबप्रोसेस के स्टड पर लगाई जाएगी।
प्रलेखन वर्णन करता है timeout=
और check=True
मैं कर सकता से बेहतर:
टाइमआउट तर्क को Popen.communicate () में पास कर दिया जाता है। यदि समय सीमा समाप्त हो जाती है, तो बच्चे की प्रक्रिया को मार दिया जाएगा और उसकी प्रतीक्षा की जाएगी। चाइल्ड प्रोसेस समाप्त होने के बाद TimeoutExpired अपवाद फिर से उठाया जाएगा।
यदि जाँच सत्य है, और प्रक्रिया एक गैर-शून्य निकास कोड के साथ बाहर निकलती है, तो CalledProcessError अपवाद उठाया जाएगा। उस अपवाद के गुण तर्कों, बाहर निकलने के कोड और stdout और stderr को पकड़ लेते हैं, यदि वे कैप्चर किए गए थे।
और यह उदाहरण मेरे लिए check=True
एक से बेहतर हो सकता है:
>>> subprocess.run("exit 1", shell=True, check=True) Traceback (most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
यहाँ एक विस्तारित हस्ताक्षर है, जैसा कि प्रलेखन में दिया गया है:
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None)
ध्यान दें कि यह इंगित करता है कि केवल आर्ग्स सूची को स्थिति से पारित किया जाना चाहिए। अतः शेष तर्कों को खोजशब्द तर्कों के रूप में पास करें।
Popen
इसके बजाय कब उपयोग करें ? मैं अकेले तर्क के आधार पर उपयोग-मामला खोजने के लिए संघर्ष करूंगा। Popen
हालाँकि, का प्रत्यक्ष उपयोग , आपको poll
'send_signal', 'समाप्त' और 'प्रतीक्षा' सहित इसके तरीकों तक पहुँच प्रदान करता है ।
यहाँ स्रोतPopen
में दिए गए अनुसार हस्ताक्षर हैं । मुझे लगता है कि यह जानकारी का सबसे सटीक इनकैप्सुलेशन है (जैसा कि विरोध किया गया है ):help(Popen)
def __init__(self, args, bufsize=-1, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
shell=False, cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0,
restore_signals=True, start_new_session=False,
pass_fds=(), *, encoding=None, errors=None):
लेकिन अधिक सूचनात्मक है प्रलेखन :Popen
subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None)
एक नई प्रक्रिया में एक बच्चा कार्यक्रम निष्पादित करें। POSIX पर, कक्षा os.execvp () का उपयोग करती है - बच्चे के कार्यक्रम को निष्पादित करने के लिए व्यवहार की तरह। Windows पर, क्लास Windows CreateProcess () फ़ंक्शन का उपयोग करता है। पोपेन के तर्क इस प्रकार हैं।
शेष प्रलेखन को समझना Popen
पाठक के लिए एक अभ्यास के रूप में छोड़ दिया जाएगा।
shell=True
सूची के रूप में या (बेहतर अभी तक) पास होना चाहिए ।
os.system
ठीक है, लेकिन दिनांकित की तरह। यह भी बहुत सुरक्षित नहीं है। इसके बजाय, प्रयास करें subprocess
। subprocess
सीधे फोन नहीं करता है और इसलिए की तुलना में अधिक सुरक्षित है os.system
।
subprocess
सभी सुरक्षा समस्याओं को दूर नहीं करता है, और इसके कुछ pesky मुद्दे हैं।
प्लम्बम भी है
>>> from plumbum import local
>>> ls = local["ls"]
>>> ls
LocalCommand(<LocalPath /bin/ls>)
>>> ls()
u'build.py\ndist\ndocs\nLICENSE\nplumbum\nREADME.rst\nsetup.py\ntests\ntodo.txt\n'
>>> notepad = local["c:\\windows\\notepad.exe"]
>>> notepad() # Notepad window pops up
u'' # Notepad window is closed by user, command returns
उपयोग:
import os
cmd = 'ls -al'
os.system(cmd)
ओएस - यह मॉड्यूल ऑपरेटिंग सिस्टम-निर्भर कार्यक्षमता का उपयोग करने का एक पोर्टेबल तरीका प्रदान करता है।
अधिक os
कार्यों के लिए, यहाँ प्रलेखन है।
यह यह सरल हो सकता है:
import os
cmd = "your command"
os.system(cmd)
मुझे इसकी सादगी के लिए शेल_कमांड काफी पसंद है । यह सबप्रोसेस मॉड्यूल के शीर्ष पर बनाया गया है।
यहाँ प्रलेखन से एक उदाहरण है:
>>> from shell_command import shell_call
>>> shell_call("ls *.py")
setup.py shell_command.py test_shell_command.py
0
>>> shell_call("ls -l *.py")
-rw-r--r-- 1 ncoghlan ncoghlan 391 2011-12-11 12:07 setup.py
-rw-r--r-- 1 ncoghlan ncoghlan 7855 2011-12-11 16:16 shell_command.py
-rwxr-xr-x 1 ncoghlan ncoghlan 8463 2011-12-11 16:17 test_shell_command.py
0
यहाँ एक और अंतर है जिसका पहले उल्लेख नहीं किया गया है।
subprocess.Popen
एक उपप्रकार के रूप में <कमांड> निष्पादित करता है। मेरे मामले में, मुझे फ़ाइल को निष्पादित करने की आवश्यकता है <a> जिसे किसी अन्य प्रोग्राम के साथ संवाद करने की आवश्यकता है, <b>।
मैंने उपप्रकार की कोशिश की, और निष्पादन सफल रहा। हालांकि <b> <a> के साथ संवाद नहीं कर सका। जब मैं टर्मिनल से दोनों चलाता हूं तो सब कुछ सामान्य है।
एक और: (नोट: kwrite अन्य अनुप्रयोगों से अलग व्यवहार करता है। यदि आप फ़ायरफ़ॉक्स के साथ नीचे की कोशिश करते हैं, तो परिणाम समान नहीं होंगे।)
यदि आप कोशिश करते हैं os.system("kwrite")
, तो प्रोग्राम फ्लो तब तक जमा होता है, जब तक उपयोगकर्ता केराइट बंद नहीं कर देता। जिसे दूर करने के लिए मैंने इसके बजाय कोशिश की os.system(konsole -e kwrite)
। यह समय कार्यक्रम जारी रहा, लेकिन केराइट कंसोल के उपप्रकार बन गए।
कोई भी व्यक्ति एक उपप्रकार नहीं होने के नाते लिखता है (यानी सिस्टम मॉनिटर में इसे पेड़ के सबसे बाएं किनारे पर दिखाई देना चाहिए)।
os.system
आपको परिणाम संग्रहीत करने की अनुमति नहीं देता है, इसलिए यदि आप किसी सूची या किसी चीज़, किसी subprocess.call
कार्य में परिणाम संग्रहीत करना चाहते हैं ।
मैं का उपयोग करते हैं उपप्रक्रिया के साथ एक साथ shlex (उद्धृत तार के भागने को संभालने के लिए):
>>> import subprocess, shlex
>>> command = 'ls -l "/your/path/with spaces/"'
>>> call_params = shlex.split(command)
>>> print call_params
["ls", "-l", "/your/path/with spaces/"]
>>> subprocess.call(call_params)
बेशर्म प्लग, मैंने इसके लिए एक लाइब्रेरी लिखी: P https://github.com/houqp/shell.py
यह मूल रूप से अब के लिए पोपेन और श्लेक्स के लिए एक आवरण है। यह पाइपिंग कमांड का भी समर्थन करता है ताकि आप पायथन में कमांड को आसान बना सकें। तो आप इस तरह की चीजें कर सकते हैं:
ex('echo hello shell.py') | "awk '{print $2}'"
विंडोज में आप बस subprocess
मॉड्यूल आयात कर सकते हैं और कॉल करके बाहरी कमांड चला सकते हैं subprocess.Popen()
, subprocess.Popen().communicate()
और subprocess.Popen().wait()
नीचे के रूप में:
# Python script to run a command line
import subprocess
def execute(cmd):
"""
Purpose : To execute a command and return exit status
Argument : cmd - command to execute
Return : exit_code
"""
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(result, error) = process.communicate()
rc = process.wait()
if rc != 0:
print "Error: failed to execute command:", cmd
print error
return result
# def
command = "tasklist | grep python"
print "This process detail: \n", execute(command)
आउटपुट:
This process detail:
python.exe 604 RDP-Tcp#0 4 5,660 K
लिनक्स के तहत, यदि आप एक बाहरी कमांड को कॉल करना चाहते हैं जो स्वतंत्र रूप से निष्पादित करेगा (अजगर स्क्रिप्ट समाप्त होने के बाद भी चालू रहेगा), आप एक साधारण कतार का उपयोग कार्य स्पूलर या कमांड पर कर सकते हैं
कार्य स्पूलर के साथ एक उदाहरण:
import os
os.system('ts <your-command>')
कार्य स्पूलर के बारे में नोट्स ( ts
):
आप चलाने के लिए समवर्ती प्रक्रियाओं की संख्या निर्धारित कर सकते हैं ("स्लॉट"):
ts -S <number-of-slots>
स्थापित करने के ts
लिए व्यवस्थापक विशेषाधिकारों की आवश्यकता नहीं होती है। आप इसे एक साधारण स्रोत से डाउनलोड और संकलित कर सकते हैं make
, इसे अपने पथ पर जोड़ सकते हैं और आपका काम हो गया।
ts
किसी भी डिस्ट्रो पर मानक नहीं है जो मुझे पता है, हालांकि सूचक at
हल्के रूप से उपयोगी है। आपको भी शायद उल्लेख करना चाहिए batch
। कहीं और के रूप में, os.system()
सिफारिश शायद कम से कम उल्लेख करना चाहिए कि subprocess
इसकी अनुशंसित प्रतिस्थापन है।
आप पोपेन का उपयोग कर सकते हैं, और फिर आप प्रक्रिया की स्थिति देख सकते हैं:
from subprocess import Popen
proc = Popen(['ls', '-l'])
if proc.poll() is None:
proc.kill()
सबप्रोसेस की जाँच करें ।
ओपनस्टैक न्यूट्रॉन से नेटवर्क आईडी लाने के लिए :
#!/usr/bin/python
import os
netid = "nova net-list | awk '/ External / { print $2 }'"
temp = os.popen(netid).read() /* Here temp also contains new line (\n) */
networkId = temp.rstrip()
print(networkId)
नोवा नेट-लिस्ट का आउटपुट
+--------------------------------------+------------+------+
| ID | Label | CIDR |
+--------------------------------------+------------+------+
| 431c9014-5b5d-4b51-a357-66020ffbb123 | test1 | None |
| 27a74fcd-37c0-4789-9414-9531b7e3f126 | External | None |
| 5a2712e9-70dc-4b0e-9281-17e02f4684c9 | management | None |
| 7aa697f5-0e60-4c15-b4cc-9cb659698512 | Internal | None |
+--------------------------------------+------------+------+
प्रिंट का आउटपुट (networkId)
27a74fcd-37c0-4789-9414-9531b7e3f126
os.popen()
2016 में सिफारिश नहीं करनी चाहिए । अवाक स्क्रिप्ट को आसानी से देशी पायथन कोड से बदला जा सकता है।
echo $PATH
का उपयोग करके करने की कोशिश कीcall(["echo", "$PATH"])
, लेकिन यह सिर्फ$PATH
किसी भी प्रतिस्थापन करने के बजाय शाब्दिक स्ट्रिंग गूँजती है । मुझे पता है कि मुझे पाथ पर्यावरण चर मिल सकता है, लेकिन मैं सोच रहा हूं कि क्या कोई आसान तरीका है जो कमांड के व्यवहार का है जैसे कि मैंने इसे बैश में निष्पादित किया था।