subprocess.check_output () मौजूद नहीं है (पायथन 2.6.5)


79

मैं सबप्रोसेसर मॉड्यूल ( यहां देखें ) के बारे में पायथन प्रलेखन पढ़ रहा हूं और यह एक के बारे में बात करता हैsubprocess.check_output() कमांड के है जो मुझे ठीक वही लगता है जिसकी मुझे आवश्यकता है।

हालाँकि, जब मैं कोशिश करता हूं और उसका उपयोग करता हूं तो मुझे एक त्रुटि मिलती है कि यह मौजूद नहीं है, और जब मैं dir(subprocess)इसे चलाता हूं तो यह सूचीबद्ध नहीं है।

मैं पायथन 2.6.5 चला रहा हूं, और मेरे द्वारा उपयोग किया गया कोड नीचे है:

import subprocess
subprocess.check_output(["ls", "-l", "/dev/null"])

किसी को भी पता नहीं है कि ऐसा क्यों हो रहा है?

जवाबों:


123

यह डॉक्स देखें 2.7 में पेश किया गया था ।

यदि आप आउटपुट चाहते हैं, तो subprocess.Popen का उपयोग करें :

>>> import subprocess
>>> output = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE).communicate()[0]

14
चेक_आउटपुट के विपरीत, यह CalledProcessErrorतब नहीं बढ़ता है जब प्रक्रिया गैर-शून्य रिटर्न कोड देती है।
— श्रीधर रत्नाकुमार

1
@ श्रीधररत्नाकुमार: बेशक, क्योंकि उनके बीच एक बड़ा अंतर है, अर्थात्: अवरुद्ध और गैर-अवरुद्ध। वे विभिन्न उपयोग के मामलों के लिए हैं!
— lpapp

मैंने इसे lambdaइस तरह से देखा check_output = lambda args: Popen(args, stdout = PIPE).communicate()[0]:। सिर्फ इसलिए कि मैं एक इंटरएक्टिव दुभाषिया में हूं और उन लोगों में मल्टीलाइन फंक्शन डीम्स लिखने के लिए पीटीए की तरह है। मैंने from subprocess import Popen, PIPEपहले सत्र में उपयोग किया ।
— आर्टऑफवर्फ

कैसे एक पिंग बनाने के लिए ?? क्या मैं अभी भी पोपेन का उपयोग कर सकता हूं या?
— theCrazyProfisor

56

यदि यह उस कोड में बहुत अधिक उपयोग किया जाता है जिसे आप चलाना चाहते हैं, लेकिन उस कोड को लंबे समय तक बनाए रखने की आवश्यकता नहीं है (या आपको भविष्य में संभावित रखरखाव सिरदर्द के बावजूद एक त्वरित फिक्स की आवश्यकता है) तो आप पंच (उर्फ बंदर पैच) को डक कर सकते हैं यह जहां भी उप-आयात किया जाता है ...

बस 2.7 से कोड उठाएं और इसे इसी तरह डालें ...

import subprocess

if "check_output" not in dir( subprocess ): # duck punch it in!
    def f(*popenargs, **kwargs):
        if 'stdout' in kwargs:
            raise ValueError('stdout argument not allowed, it will be overridden.')
        process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
        output, unused_err = process.communicate()
        retcode = process.poll()
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
            raise subprocess.CalledProcessError(retcode, cmd)
        return output
    subprocess.check_output = f

मामूली विदाई की आवश्यकता हो सकती है।

हालांकि इस तरह गंदे छोटे backports बनाए रखने के लिए onus आप पर है ध्यान में रखें। यदि बग्स की खोज की गई है और नवीनतम अजगर में सुधार किया गया है, तो आपको a) यह ध्यान रखना होगा कि यदि आप सुरक्षित रहना चाहते हैं तो b) अपने संस्करण को अपडेट करें। इसके अलावा, आंतरिक कार्यों को ओवरराइड करना और परिभाषित करना अपने आप में अगले लड़के का सबसे बुरा सपना है, खासकर तब जब अगला लड़का आप लाइन से कई साल नीचे हो और आप पिछली बार किए गए घमासान हैक के बारे में सब भूल गए हों! संक्षेप में: यह बहुत कम ही एक अच्छा विचार है।


2
मैं इस विधि से सम्‍मिलित हूं। मैं शायद स्रोत का स्थान शामिल करूंगा। आप इसे hg.python.org/cpython/file/d37f963394aa/Lib/subprocess.py#l544
— Ehtesh Choudhury

1
नोट: CalledProcessError अजगर 2.6 में आउटपुट को स्वीकार नहीं करता है। (इस हैक का उपयोग करने के बाद मुझे तुरंत काट लिया गया !:()
— एंडी हेडन

cpython अब GitHub पर है - check_outputPython के लिए 2.7 यहाँ वर्तमान में है: github.com/python/cpython/blob/2.7/Lib/subprocess.py#L194
— james

6

बंदर पैच सुझाव के लिए धन्यवाद (और मेरे प्रयास विफल रहे - लेकिन हम CalledProcessError आउटपुट का उपभोग कर रहे थे, इसलिए बंदर पैच की आवश्यकता थी))

यहां एक काम करने वाला 2.6 पैच मिला: http://pydoc.net/Python/pep8radius/0.9.0/pep8radius.shell/

"""Note: We also monkey-patch subprocess for python 2.6 to
give feature parity with later versions.
"""
try:
    from subprocess import STDOUT, check_output, CalledProcessError
except ImportError:  # pragma: no cover
    # python 2.6 doesn't include check_output
    # monkey patch it in!
    import subprocess
    STDOUT = subprocess.STDOUT

    def check_output(*popenargs, **kwargs):
        if 'stdout' in kwargs:  # pragma: no cover
            raise ValueError('stdout argument not allowed, '
                             'it will be overridden.')
        process = subprocess.Popen(stdout=subprocess.PIPE,
                                   *popenargs, **kwargs)
        output, _ = process.communicate()
        retcode = process.poll()
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
            raise subprocess.CalledProcessError(retcode, cmd,
                                                output=output)
        return output
    subprocess.check_output = check_output

    # overwrite CalledProcessError due to `output`
    # keyword not being available (in 2.6)
    class CalledProcessError(Exception):

        def __init__(self, returncode, cmd, output=None):
            self.returncode = returncode
            self.cmd = cmd
            self.output = output

        def __str__(self):
            return "Command '%s' returned non-zero exit status %d" % (
                self.cmd, self.returncode)
    subprocess.CalledProcessError = CalledProcessError
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.