दिलचस्प पोस्ट
मुझे एक लिस्टेड लिस्टेड लिस्ट का उपयोग कब करना चाहिए वेबव्यू में फ़ाइल डाउनलोड करें सदस्य कलेक्शन के खुलासे के लिए केवलपढ़नेयोग्यकलेक्शन या पहला असंख्य? कोड में WPF छवि स्रोत सेट करना सी # में प्रारूप की तारीख जावास्क्रिप्ट और PHP के बीच अंतर पायथन: सूची पर जाने के दौरान सूची तत्व को हटाने सेटिंग्स में परिभाषित मूल्य के लिए बाइंड करें कैसे वर्डप्रेस के साथ URL में अतिरिक्त चर को पारित करने के लिए निर्धारित करना कि कोई वस्तु आदिम प्रकार का है कैसे एक सरणी सूची का उपयोग करने के लिए? मैं हेक्स स्ट्रिंग से UIColor कैसे बना सकता हूं? HTML तत्व ऐरे, नाम = "कुछ " या नाम = "कुछ"? मुझे जेपीए मिले, या समान रूप से, डीएओ पैटर्न को प्रोत्साहित न करें सी # के साथ XML से सभी नामस्थानों को कैसे निकालें?

पायथन से शेल कमांड चलाने और आउटपुट कैप्चर करना

मैं एक ऐसा समारोह लिखना चाहता हूं जो शेल कमांड को निष्पादित करेगा और स्ट्रिंग के रूप में अपना आउटपुट लौटाएगा, चाहे कोई त्रुटि हो या सफल संदेश। मैं सिर्फ एक ही परिणाम प्राप्त करना चाहता हूँ कि मैं कमांड लाइन के साथ मिल गया होगा

एक ऐसा कोड उदाहरण क्या होगा जो ऐसा करना होगा?

उदाहरण के लिए:

def run_command(cmd): # ?????? print run_command('mysqladmin create test -uroot -pmysqladmin12') # Should output something like: # mysqladmin: CREATE DATABASE failed; error: 'Can't create database 'test'; database exists' 

वेब के समाधान से एकत्रित समाधान "पायथन से शेल कमांड चलाने और आउटपुट कैप्चर करना"

इस प्रश्न का उत्तर आपके द्वारा उपयोग किए जा रहे अजगर के संस्करण पर निर्भर करता है। सरल तरीका subprocess.check_outputsubprocess.check_output का उपयोग करना है:

 >>> subprocess.check_output(['ls', '-l']) b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n' 

check_output एक प्रोग्राम चलाता है जो इनपुट के रूप में केवल तर्क लेता है। 1 यह परिणाम बिल्कुल के रूप में stdout मुद्रित करता है। यदि आपको stdin को इनपुट लिखने की आवश्यकता है, तो आगे run या Popen सेक्शन पर जाएं। यदि आप जटिल शेल कमानों को निष्पादित करना चाहते हैं, तो इस उत्तर के अंत में shell=True पर नोट देखें।

check_output फ़ंक्शन अजगर के लगभग सभी संस्करणों पर अब भी व्यापक उपयोग (2.7+) में काम करता है। 2 लेकिन हाल के संस्करणों के लिए, यह अब अनुशंसित दृष्टिकोण नहीं है

अजगर के आधुनिक संस्करण (3.5 या उच्च): run

यदि आप पायथन 3.5 या उच्चतर का उपयोग कर रहे हैं, और पिछली संगतता की आवश्यकता नहीं है , तो नए run फ़ंक्शन की सिफारिश की जाती है। यह subprocess मॉड्यूल के लिए एक बहुत सामान्य, उच्च-स्तरीय एपीआई प्रदान करता है। किसी प्रोग्राम के आउटपुट को कैप्चर करने के लिए, subprocess.PIPE फ्लैग को stdout कीवर्ड तर्क में पास करें। फिर लौटा CompletedProcess ऑब्जेक्ट की stdout विशेषता का उपयोग करें:

 >>> import subprocess >>> result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE) >>> result.stdout b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n' 

वापसी मान एक bytes ऑब्जेक्ट है, इसलिए यदि आप उचित स्ट्रिंग चाहते हैं, तो आपको इसे decode होगा। मानित प्रक्रिया को मानते हुए यूटीएफ -8-एन्कोडेड स्ट्रिंग रिटर्न:

 >>> result.stdout.decode('utf-8') 'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n' 

यह सब एक-लाइनर में संकुचित हो सकता है:

 >>> subprocess.run(['ls', '-l'], stdout=subprocess.PIPE).stdout.decode('utf-8') 'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n' 

यदि आप प्रक्रिया के stdin को इनपुट देना चाहते हैं, तो input कीवर्ड तर्क में एक bytes ऑब्जेक्ट पास करें:

 >>> cmd = ['awk', 'length($0) > 5'] >>> input = 'foo\nfoofoo\n'.encode('utf-8') >>> result = subprocess.run(cmd, stdout=subprocess.PIPE, input=input) >>> result.stdout.decode('utf-8') 'foofoo\n' 

आप stderr=subprocess.PIPE ( result.stderr पर कब्जा) या stderr=subprocess.STDOUT (नियमित उत्पादन के साथ result.stdout पर कब्जा) के पास त्रुटियों पर कब्जा कर सकते हैं। जब सुरक्षा कोई चिंता नहीं है, तो आप shell=True गुजरने वाले अधिक जटिल शेल आदेशों को भी नीचे चला सकते हैं।

यह काम करने के पुराने तरीके की तुलना में जटिलता का थोड़ा सा जोड़ता है लेकिन मुझे लगता है कि यह अदायगी के लायक है: अब आप अकेले run फ़ंक्शन के साथ कुछ भी करने की ज़रूरत कर सकते हैं।

पायथन के पुराने संस्करण (2.7-3.4): check_output

यदि आप पायथन के पुराने संस्करण का उपयोग कर रहे हैं, या थोड़े पीछे की संगतता की आवश्यकता है, तो संभवतः आप check_output फ़ंक्शन का उपयोग संक्षिप्त रूप से वर्णित रूप में कर सकते हैं। यह पायथन 2.7 के बाद से उपलब्ध है।

 subprocess.check_output(*popenargs, **kwargs) 

यह लेता है Popen (नीचे देखें) के रूप में एक ही तर्क लेता है, और एक स्ट्रिंग देता है जिसमें प्रोग्राम का आउटपुट होता है। इस उत्तर की शुरुआत में अधिक विस्तृत उपयोग उदाहरण हैं

आप यह सुनिश्चित करने के लिए stderr=subprocess.STDOUT पास कर सकते हैं कि त्रुटि संदेशों को आउटपुट में शामिल किया गया है – लेकिन stderr=subprocess.PIPE को check_output पास नहीं check_output । इससे डेडलॉक हो सकता है जब सुरक्षा कोई चिंता नहीं है, तो आप shell=True गुजरने वाले अधिक जटिल शेल आदेशों को भी नीचे चला सकते हैं।

यदि आपको stderr से पाइप या प्रक्रिया को इनपुट पास करने की आवश्यकता है, तो check_output कार्य पर निर्भर नहीं होगा। उस मामले में नीचे दिए गए Popen उदाहरणों को देखें।

कॉम्प्लेक्स अनुप्रयोगों और Popen विरासत संस्करण (2.6 और नीचे): Popen

अगर आपको गहरी पिछली संगतता की आवश्यकता है, या यदि आपको check_output प्रदान की तुलना में अधिक परिष्कृत कार्यक्षमता की check_output है, तो आपको सीधे Popen ऑब्जेक्ट्स के साथ काम करना होगा, जो Popen लिए निम्न स्तरीय Popen को Popen हैं।

Popen कन्स्ट्रक्टर बिना किसी एक Popen स्वीकार करता है, या एक सूची जिसमें पहले आइटम के रूप में एक कमांड है, उसके बाद किसी भी संख्या में तर्क, प्रत्येक सूची में एक अलग आइटम के रूप में। shlex.split उचित स्वरूपित सूची में स्ट्रिंग्स को पार्स करने में मदद कर सकता है। Popen ऑब्जेक्ट प्रक्रिया IO प्रबंधन और निम्न-स्तरीय कॉन्फ़िगरेशन के लिए विभिन्न तर्कों को भी स्वीकार करते हैं।

इनपुट और कैप्चर आउटपुट भेजने के लिए, communicate लगभग हमेशा पसंदीदा विधि होता है। जैसे की:

 output = subprocess.Popen(["mycmd", "myarg"], stdout=subprocess.PIPE).communicate()[0] 

या

 >>> import subprocess >>> p = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE, ... stderr=subprocess.PIPE) >>> out, err = p.communicate() >>> print out . .. foo 

यदि आप stdin=PIPE सेट करते हैं, तो communicate भी आपको stdin माध्यम से डेटा को पास करने की अनुमति देता है:

 >>> cmd = ['awk', 'length($0) > 5'] >>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE, ... stderr=subprocess.PIPE, ... stdin=subprocess.PIPE) >>> out, err = p.communicate('foo\nfoofoo\n') >>> print out foofoo 

हारून हॉल का जवाब दें, जो इंगित करता है कि कुछ सिस्टम पर, आपको DEVNULL , और DEVNULL को सभी को काम करने के लिए communicate करने के लिए PIPE (या DEVNULL ) में सेट करना पड़ सकता है।

कुछ दुर्लभ मामलों में, आपको जटिल, रीयल-टाइम आउटपुट कैप्चरिंग की आवश्यकता हो सकती है। वर्टेक का उत्तर आगे बढ़ने का सुझाव देता है, लेकिन communicate अलावा अन्य तरीकों से सावधानी से उपयोग नहीं किए जाने पर डेडलॉक की संभावनाएं हैं

सभी उपर्युक्त कार्यों के साथ, जब सुरक्षा कोई चिंता नहीं है, तो आप shell=True गुजरने के द्वारा अधिक जटिल शेल कमांड चला सकते हैं।

टिप्पणियाँ

1. शेल कमांड चलाना: shell=True तर्क

आम तौर पर, run लिए प्रत्येक कॉल, check_output , या Popen कन्स्ट्रक्टर एक प्रोग्राम को निष्पादित करता है। इसका अर्थ है कोई फैंसी बाश-स्टाइल पाइप नहीं। यदि आप जटिल शेल कमानों को चलाने के लिए चाहते हैं, तो आप shell=True पास कर सकते हैं, जो सभी तीन फ़ंक्शन का समर्थन करते हैं।

हालांकि, ऐसा करने से सुरक्षा चिंताओं को बढ़ाया जाता है यदि आप हल्की पटकथा से अधिक कुछ कर रहे हैं, तो आप प्रत्येक प्रक्रिया को अलग से बुला सकते हैं, और इनपुट के रूप में प्रत्येक से अगले उत्पादन को पास कर सकते हैं

 run(cmd, [stdout=etc...], input=other_output) 

या

 Popen(cmd, [stdout=etc...]).communicate(other_output) 

सीधे कनेक्ट पाइप के प्रलोभन मजबूत है; इसका प्रतिरोध करें। अन्यथा, आप डेडलॉक देखेंगे या इस तरह की हैमी चीजें करना होगा ।

2. यूनिकोड विचार

check_output पायथन 2 में एक स्ट्रिंग लौटाता है, लेकिन एक bytes ऑब्जेक्ट पायथन 3 में है। यदि आपके पास पहले से ही नहीं है तो यूनिकोड के बारे में जानने के लिए एक पल लेने योग्य है।

यह आसान तरीका है, लेकिन केवल यूनिक्स (सिगविन सहित) पर काम करता है।

 import commands print commands.getstatusoutput('wc -l file') 

यह (वापसी_वल्यू, आउटपुट) के साथ एक ट्यूपल देता है

ऐसा कुछ:

 def runProcess(exe): p = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) while(True): retcode = p.poll() #returns None while subprocess is running line = p.stdout.readline() yield line if(retcode is not None): break 

ध्यान दें, मैं stderr को stdout पर पुनर्निर्देशित कर रहा हूं, हो सकता है कि वह ठीक वही न हो जो आप चाहते हैं, लेकिन मुझे त्रुटि संदेश भी चाहिए।

यह फ़ंक्शन लाइन के रूप में लाइन के रूप में उत्पन्न होती है (सामान्य रूप से आपको उपप्रक्रिया के लिए पूर्ण रूप से आउटपुट प्राप्त करने के लिए इंतजार करना होगा)

आपके मामले के लिए यह प्रयोग होगा:

 for line in runProcess('mysqladmin create test -uroot -pmysqladmin12'.split()): print line, 

वर्टेक का जवाब सभी पंक्तियों को नहीं पढ़ता है, इसलिए मैंने ऐसा संस्करण बनाया जो कि किया था:

 def run_command(command): p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) return iter(p.stdout.readline, b'') 

उपयोग स्वीकार किए गए उत्तर के समान है:

 command = 'mysqladmin create test -uroot -pmysqladmin12'.split() for line in run_command(command): print(line) 

यह एक मुश्किल लेकिन सुपर सरल समाधान है जो कई स्थितियों में काम करता है:

 import os os.system('sample_cmd > tmp') print open('tmp', 'r').read() 

एक अस्थायी फ़ाइल (यहां टीएमपी है) कमांड के आउटपुट के साथ बनाई गई है और आप इसे अपने वांछित आउटपुट से पढ़ सकते हैं।

टिप्पणियों से अतिरिक्त नोट: आप एक बार नौकरी के मामले में tmp फ़ाइल को निकाल सकते हैं। यदि आपको यह कई बार करने की आवश्यकता है, तो tmp को हटाने की कोई आवश्यकता नहीं है।

 os.remove('tmp') 

आधुनिक पायथन समाधान (> = 3.1):

  res = subprocess.check_output(lcmd, stderr=subprocess.STDOUT) 

आपका माइलेज मे भिन्न हो, मैंने पाइथन 2.6.5 पर विंडोज में वर्टेक के समाधान पर @ प्रेषक की स्पिन का प्रयास किया, लेकिन मुझे त्रुटियां मिल रही थीं, और कोई अन्य समाधान काम नहीं किया। मेरी त्रुटि थी: WindowsError: [Error 6] The handle is invalid

मुझे पता चला कि मुझे हर आउटलेट को पाइप को असाइन करना था, जो मुझे अपेक्षित उत्पादन वापस करने के लिए मिला – मेरे लिए निम्नलिखित काम किया।

 import subprocess def run_command(cmd): """given shell command, returns communication tuple of stdout and stderr""" return subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE).communicate() 

और इस तरह कॉल करें, ( [0] ट्यूपल, stdout का पहला तत्व प्राप्त होता है):

 run_command('tracert 11.1.0.1')[0] 

अधिक सीखने के बाद, मेरा मानना ​​है कि मुझे इन पाइप तर्कों की आवश्यकता है क्योंकि मैं एक कस्टम सिस्टम पर काम कर रहा हूं जो अलग-अलग हैंडल का उपयोग करता है, इसलिए मुझे सीधे सभी एसटीडी के नियंत्रण को करना पड़ा।

कंसोल पॉपअप (Windows के साथ) को रोकने के लिए, यह करें:

 def run_command(cmd): """given shell command, returns communication tuple of stdout and stderr""" # instantiate a startupinfo obj: startupinfo = subprocess.STARTUPINFO() # set the use show window flag, might make conditional on being in Windows: startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW # pass as the startupinfo keyword argument: return subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, startupinfo=startupinfo).communicate() run_command('tracert 11.1.0.1') 

पायथन 3.5 में:

 import subprocess output = subprocess.run("ls -l", shell=True, stdout=subprocess.PIPE, universal_newlines=True) print(output.stdout) 

मैं निम्नलिखित आवश्यकताओं के साथ एक ही समस्या का एक थोड़ा अलग स्वाद था:

  1. एसटीडीओयूटी बफर (यानी वास्तविक समय में) में जमा होने पर एसटीडीओटी संदेशों को कैप्चर करें और वापस लौटाएं।
    • @vartec ने इस पायथन को जनरेटर के उपयोग और 'उपज' के साथ हल किया
      उपरोक्त खोजशब्द
  2. सभी एसटीडीओटी लाइनों को मुद्रित करें ( भले ही STDOUT बफर से पहले पूरी प्रक्रिया पूरी हो सकती है )
  3. उच्च आवृत्ति पर प्रक्रिया को मतदान करने वाले CPU चक्र को बर्बाद मत करना
  4. सबप्रोसेक्शन का रिटर्न कोड जांचें
  5. अगर हम एक शून्य-शून्य त्रुटि रिटर्न कोड प्राप्त करते हैं तो STDERR प्रिंट करें (STDOUT से अलग)।

मैंने निम्नलिखित के साथ आने के लिए पिछले उत्तर जोड़ दिए हैं और छूटे हैं:

 import subprocess from time import sleep def run_command(command): p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) # Read stdout from subprocess until the buffer is empty ! for line in iter(p.stdout.readline, b''): if line: # Don't print blank lines yield line # This ensures the process has completed, AND sets the 'returncode' attr while p.poll() is None: sleep(.1) #Don't waste CPU-cycles # Empty STDERR buffer err = p.stderr.read() if p.returncode != 0: # The run_command() function is responsible for logging STDERR print("Error: " + str(err)) 

यह कोड पिछले उत्तरों के समान ही निष्पादित होगा:

 for line in run_command(cmd): print(line) 

आप किसी भी शेल कमांड को चलाने के लिए निम्न कमांड का उपयोग कर सकते हैं। मैंने उन्हें उबुंटू पर इस्तेमाल किया है

 import os os.popen('your command here').read() 

मेरे पास एक ही समस्या थी लेकिन इस का पालन करने का एक बहुत आसान तरीका पता चला है

 import subprocess Input = subprocess.getoutput("ls -l") print(Input) 

आशा है कि यह मदद करता है

नोट: यह समाधान python3 विशिष्ट है क्योंकि उपप्रोसेस.आउटआउटपुट subprocess.getoutput() पायथन 2 में काम नहीं करता है

यदि आपको एकाधिक फ़ाइलों पर शेल कमांड चलाने की आवश्यकता है, तो यह मेरे लिए चाल है

 import os import subprocess # Define a function for running commands and capturing stdout line by line # (Modified from Vartec's solution because it wasn't printing all lines) def runProcess(exe): p = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) return iter(p.stdout.readline, b'') # Get all filenames in working directory for filename in os.listdir('./'): # This command will be run on each file cmd = 'nm ' + filename # Run the command and capture the output line by line. for line in runProcess(cmd.split()): # Eliminate leading and trailing whitespace line.strip() # Split the output output = line.split() # Filter the output and print relevant lines if len(output) > 2: if ((output[2] == 'set_program_name')): print filename print line 

संपादित करें: बस जेएफ सेबस्टियन के सुझाव के साथ मैक्स पर्स्सन के समाधान को देखा। आगे बढ़ो और इसमें शामिल किया।

उदाहरण के लिए, निष्पादित करें ('एलएस -एएचएल') तीन / चार संभावित रिटर्न और ओएस प्लेटफार्मों को विभेदित किया गया है:

  1. कोई आउटपुट नहीं है, लेकिन सफलतापूर्वक चलाएं
  2. आउटपुट रिक्त रेखा, सफलतापूर्वक चलाना
  3. रन विफल
  4. कुछ आउटपुट, सफलतापूर्वक चलाना

नीचे कार्य करें

 def execute(cmd, output=True, DEBUG_MODE=False): """Executes a bash command. (cmd, output=True) output: whether print shell output to screen, only affects screen display, does not affect returned values return: ...regardless of output=True/False... returns shell output as a list with each elment is a line of string (whitespace stripped both sides) from output could be [], ie, len()=0 --> no output; [''] --> output empty line; None --> error occured, see below if error ocurs, returns None (ie, is None), print out the error message to screen """ if not DEBUG_MODE: print "Command: " + cmd # https://stackoverflow.com/a/40139101/2292993 def _execute_cmd(cmd): if os.name == 'nt' or platform.system() == 'Windows': # set stdin, out, err all to PIPE to get results (other than None) after run the Popen() instance p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) else: # Use bash; the default is sh p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, executable="/bin/bash") # the Popen() instance starts running once instantiated (??) # additionally, communicate(), or poll() and wait process to terminate # communicate() accepts optional input as stdin to the pipe (requires setting stdin=subprocess.PIPE above), return out, err as tuple # if communicate(), the results are buffered in memory # Read stdout from subprocess until the buffer is empty ! # if error occurs, the stdout is '', which means the below loop is essentially skipped # A prefix of 'b' or 'B' is ignored in Python 2; # it indicates that the literal should become a bytes literal in Python 3 # (eg when code is automatically converted with 2to3). # return iter(p.stdout.readline, b'') for line in iter(p.stdout.readline, b''): # # Windows has \r\n, Unix has \n, Old mac has \r # if line not in ['','\n','\r','\r\n']: # Don't print blank lines yield line while p.poll() is None: sleep(.1) #Don't waste CPU-cycles # Empty STDERR buffer err = p.stderr.read() if p.returncode != 0: # responsible for logging STDERR print("Error: " + str(err)) yield None out = [] for line in _execute_cmd(cmd): # error did not occur earlier if line is not None: # trailing comma to avoid a newline (by print itself) being printed if output: print line, out.append(line.strip()) else: # error occured earlier out = None return out else: print "Simulation! The command is " + cmd print ""