पाइथन में बैश बैकटिक्स के बराबर [डुप्लिकेट]


84

पाइथन में रूबी और पर्ल में पाए जाने वाले बैकटिक्स के बराबर क्या है? यही है, रूबी में मैं यह कर सकता हूं:

foo = `cat /tmp/baz`

पायथन में समतुल्य कथन कैसा दिखता है? मैंने कोशिश की है, os.system("cat /tmp/baz")लेकिन यह परिणाम को मानक के बाहर रखता है और मुझे उस ऑपरेशन के त्रुटि कोड पर लौटाता है।


जवाबों:


100
output = os.popen('cat /tmp/baz').read()

4
@mckenzm प्रश्न बाहरी प्रक्रिया के आउटपुट को कैप्चर करने के बारे में है। पायथन फ़ंक्शन के आउटपुट को कैप्चर करना काफी अलग प्रश्न होगा।
जॉन कुगेलमैन

1
आश्चर्यजनक रूप से संक्षिप्त, और वास्तव में रूबी के बराबर `...`(स्टैडआउट पर कब्जा करना, पासिंग स्टॉडर के माध्यम से) - एक अपवाद के साथ: रूबी $?तथ्य के बाद के माध्यम से प्रक्रिया के निकास कोड को निर्धारित करने की अनुमति देता है; पायथन में, जो मैं बता सकता हूं, उसके लिए आपको subprocessमॉड्यूल के कार्यों का उपयोग करना होगा ।
21

82

subprocessमॉड्यूल का उपयोग करने के लिए सबसे लचीला तरीका है :

import subprocess

out = subprocess.run(["cat", "/tmp/baz"], capture_output=True)
print("program output:", out)

capture_outputपायथन 3.7 में पेश किया गया था, पुराने संस्करणों के लिए check_output()इसके बजाय विशेष फ़ंक्शन का उपयोग किया जा सकता है:

out = subprocess.check_output(["cat", "/tmp/baz"])

यदि आप ठीक दानेदार नियंत्रण की आवश्यकता है, तो आप मैन्युअल रूप से एक उपप्रकार वस्तु का निर्माण भी कर सकते हैं:

proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE)
(out, err) = proc.communicate()

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


2
हां, यह एकमात्र एकमात्र तरीका है, आप इसे एक फ़ंक्शन में लपेट सकते हैं ताकि आप निष्पादित ("कमांड") की तरह कुछ कह सकें
विन्को वेर्सालोविच

यह वास्तव में मेरे लिए काम नहीं करता है, क्योंकि इस मामले में, बाज एक निर्देशिका है और मैं उस निर्देशिका में सभी फ़ाइलों की सामग्री प्राप्त करने की कोशिश कर रहा हूं। (बिल्ली / tmp / baz / * टिक्स में काम करता है, लेकिन यहां वर्णित विधि के माध्यम से नहीं)
क्रिस बंच

6
पुनः: "*" काम नहीं करता है; इसके बजाय उपप्रोसेस। पॉपेन (["कैट", "/ tmp / baz"], stdout = subprocess.PIPE, शेल = ट्रू) का उपयोग करें। चूँकि ग्लोब (तारा) विस्तार को शेल द्वारा नियंत्रित किया जाता है, इसलिए सबप्रोसेसिंग मॉड्यूल को इस मामले में शेल विस्तार का उपयोग करना चाहिए (बशर्ते / बिन या शेड द्वारा)।
पासी सावोलेनैन

1
से docs.python.org/2/library/subprocess.html#popen-constructor "अगर आर्ग एक दृश्य, पहला आइटम निर्दिष्ट कमांड स्ट्रिंग है, और किसी भी अतिरिक्त आइटम अतिरिक्त तर्कों के रूप में माना जाएगा (शेल = सच के साथ): खोल के लिए ही। इसलिए, यदि आप शेल = ट्रू का उपयोग करने जा रहे हैं, तो पहला एर्ग शायद स्ट्रिंग "कैट / टैम्प / बाज़" होना चाहिए। वैकल्पिक रूप से, यदि आप पहले arg के रूप में एक क्रम का उपयोग करना चाहते हैं तो आपको शेल = फाल्स का उपयोग करना चाहिए
onlynone

1
@gerrit: यह पदावनत नहीं है। डॉक्स सलाह देते हैं subprocess.run() (मुझे नहीं पता कि यह योग्य है) यदि आपको पहले के संस्करणों का समर्थन करने की आवश्यकता नहीं है या यदि आपको इसके द्वारा दिए गए लचीलेपन की आवश्यकता नहीं है Popen()
JFS

27

sth सही है । आप os.popen () का उपयोग भी कर सकते हैं, लेकिन जहां उपलब्ध (पायथन 2.4+) उपप्रकार आमतौर पर बेहतर होता है।

हालांकि, कुछ भाषाओं के विपरीत, जो इसे प्रोत्साहित करती हैं, यह आमतौर पर एक उपप्रकार को फैलाने के लिए बुरा रूप माना जाता है जहां आप भाषा के अंदर एक ही काम कर सकते हैं। यह धीमा, कम विश्वसनीय और प्लेटफ़ॉर्म-निर्भर है। आपका उदाहरण बेहतर होगा:

foo= open('/tmp/baz').read()

ईटा:

baz एक निर्देशिका है और मैं उस निर्देशिका की सभी फ़ाइलों की सामग्री प्राप्त करने का प्रयास कर रहा हूं

? एक निर्देशिका पर बिल्ली मुझे एक त्रुटि मिलती है।

यदि आप फ़ाइलों की सूची चाहते हैं:

import os
foo= os.listdir('/tmp/baz')

यदि आप एक निर्देशिका में सभी फ़ाइलों की सामग्री चाहते हैं, तो कुछ इस तरह है:

contents= []
for leaf in os.listdir('/tmp/baz'):
    path= os.path.join('/tmp/baz', leaf)
    if os.path.isfile(path):
        contents.append(open(path, 'rb').read())
foo= ''.join(contents)

या, यदि आप सुनिश्चित कर सकते हैं कि वहां कोई निर्देशिका नहीं है, तो आप इसे एक-लाइनर में फिट कर सकते हैं:

path= '/tmp/baz'
foo= ''.join(open(os.path.join(path, child), 'rb').read() for child in os.listdir(path))

1
हालांकि यह सवाल का जवाब नहीं था, यह उपयोगकर्ताओं को शिक्षित करने के लिए सबसे अच्छा जवाब है।
दोपहर

1
सवाल का शीर्षक "बैकटिक्स के बराबर क्या है" है। मैंने मान लिया कि "बिल्ली" सिर्फ एक उदाहरण था। यह उत्तर सामान्य मामले में मदद नहीं करता है।
जेसन

15
foo = subprocess.check_output(["cat", "/tmp/baz"])

3
यह अब तक का सबसे सीधा रास्ता है। पायथन 2.7 में "subprocess.check_output" जोड़ा गया था, जो जुलाई 2010 में जारी किया गया था, अन्य "पोपेन" जवाब दिए जाने के बाद।
रॉबर्ट फ्लेमिंग

10

पायथन 3.5 आगे से, अनुशंसित तरीका उपयोग करना है subprocess.run। पायथॉन 3.7 के बाद से, जैसा आप वर्णन करते हैं, वैसा ही व्यवहार पाने के लिए, आप उपयोग करेंगे:

cpe = subprocess.run("ls", shell=True, capture_output=True)

इससे कोई subprocess.CompletedProcessवस्तु वापस आ जाएगी । स्टडआउट के लिए आउटपुट में होगा cpe.stdout, स्टडर के लिए आउटपुट में होगा cpe.stderr, जो दोनों bytesऑब्जेक्ट होंगे। आप किसी strऑब्जेक्ट को प्राप्त करने के लिए आउटपुट को डिकोड कर सकते हैं cpe.stdout.decode()या पास होने text=Trueसे प्राप्त कर सकते हैं subprocess.run:

cpe = subprocess.run("ls", shell=True, capture_output=True, text=True)

बाद के मामले में, cpe.stdoutऔर cpe.stderrदोनों strवस्तुएं हैं।


अजगर 3.7 से आप text=Trueबाइट्स के बजाय एक वापस पाने के लिए पैरामीटर का उपयोग कर सकते हैं ।
bwv549


3
import os
foo = os.popen('cat /tmp/baz', 'r').read()

3
यह रूबी के बैकटिक्स के बराबर है, लेकिन अगर आपकी समस्या किसी निर्देशिका की सामग्री को सूचीबद्ध करना है तो यह करने का सबसे अच्छा तरीका नहीं है।
जागृति

2

मैं उपयोग कर रहा हूँ

(६: ०) $ अजगर - विसर्जन पायथन २. 0.१

उपरोक्त उदाहरणों में से एक है:

import subprocess
proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
print "program output:", out

मेरे लिए, यह निर्देशिका / tmp तक पहुँचने में विफल रहा। उपप्रकार के लिए डॉक्टर स्ट्रिंग को देखने के बाद मैंने प्रतिस्थापित किया

["प्रोग", "अर्ग"]

साथ में

"प्रोग आर्ग"

और खोल विस्तार का व्यवहार मिला जो वांछित था (एक ला पर्ल का `ठेला arg`)

प्रिंट सबप्रोसेस। पोपेन ("ls -ld / tmp / v *", stdout = subprocess.PIPE, शेल = ट्रू) .communicate () [0]।


मैंने थोड़ी देर पहले अजगर का उपयोग करना छोड़ दिया क्योंकि मैं perl `cmd ...` के बराबर करने की कठिनाई से नाराज था। मुझे खुशी है कि पायथन ने इसे उचित बनाया है।


1

यदि आप उपप्रोसेस का उपयोग करते हैं। तो, bufsize निर्दिष्ट करना याद रखें। डिफ़ॉल्ट 0 है, जिसका अर्थ है "असंबद्ध", न कि "एक उचित डिफ़ॉल्ट चुनें"।


1

यह python3 में काम नहीं करेगा, लेकिन python2 में आप strएक कस्टम __repr__विधि के साथ विस्तार कर सकते हैं जो आपके शेल कमांड को कॉल करता है और इसे इस तरह लौटाता है:

#!/usr/bin/env python

import os

class Command(str):
    """Call system commands"""

    def __repr__(cmd):
        return os.popen(cmd).read()

जिसे आप पसंद कर सकते हैं

#!/usr/bin/env python
from command import Command

who_i_am = `Command('whoami')`

# Or predeclare your shell command strings
whoami = Command('whoami')
who_i_am = `whoami`

4
इसके अलावा आपको शायद ऐसा नहीं करना चाहिए
ThorSummoner

-1

repr()

backtick( `) ऑपरेटर हटा दिया गया था में Python 3। यह एक एकल उद्धरण के समान भ्रामक है, और कुछ कीबोर्ड पर टाइप करना कठिन है। इसके बजाय backtick, समान अंतर्निहित फ़ंक्शन का उपयोग करें repr()


यह बैश बैकटिक्स के बराबर नहीं है।
गेरिट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.