2009-09-11 9 views
73

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

foo = `cat /tmp/baz` 

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

import subprocess 

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

आप कॉल * साथ फ़ाइल नाम विस्तार पाने के लिए उदाहरण के लिए, खोल के माध्यम से पारित करने के लिए चाहते हैं, तो आप shell=True पैरामीटर का उपयोग कर सकते हैं:

+0

http://stackoverflow.com/questions/2924310/whats-a-good-equivalent-to-pythons-subprocess-check-call-that-returns-the-conte – jfs

उत्तर

78
output = os.popen('cat /tmp/baz').read() 
+0

यह सुनिश्चित नहीं है कि मैं ओपी के उदाहरण के बाहर इसका उपयोग कैसे करूं। यहां कोई भी जवाब शुद्ध प्रश्न को संबोधित करने के लिए प्रतीत नहीं होता है। उदाहरण के लिए। lambda कार्यों के बिना 'string'.somemethod "के परिणामस्वरूप कुछ फ़ंक्शन कैसे करें। – mckenzm

+2

@mckenzm प्रश्न बाहरी प्रक्रिया के आउटपुट को कैप्चर करने के बारे में है। पाइथन फ़ंक्शन के आउटपुट को कैप्चर करना एक अलग सवाल होगा। –

77

सबसे लचीला तरीका subprocess मॉड्यूल का उपयोग करने के लिए है। यदि आप ऐसा करते हैं, तो आप एक स्ट्रिंग, उद्धृत/... की तरह आप इसे एक खोल प्रॉम्प्ट पर टाइप करेंगे के रूप में आदेश प्रदान करने के लिए है:

proc = subprocess.Popen('cat /tmp/ba* "s p a c e.txt"', shell=True, ...) 
+2

हाँ, यह एकमात्र रास्ता है, आप इसे फ़ंक्शन में लपेट सकते हैं ताकि आप निष्पादन ("कमांड") –

+0

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

+6

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

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

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

25

sth is right। आप 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)) 
+0

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

+0

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

1

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

2

मैं

(6: 0) का उपयोग कर रहा $ अजगर --version अजगर 2.7.1

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

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

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

[ "prog", "आर्ग"]

"prog आर्ग"

साथ

और मिल गया शेल विस्तार व्यवहार जो वांछित था (एक ला पर्ल का 'प्रॉग Arg`)

प्रिंट subprocess.Popen ("ls -LD/tmp/v *", stdout = subprocess.PIPE, खोल = सच) .communicate() [0]


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

14
foo = subprocess.check_output(["cat", "/tmp/baz"]) 
+0

इसे करने का सबसे अच्छा तरीका। :) – Gandaro

+3

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

4

आदेश पैकेज का उपयोग करने का सबसे आसान तरीका है।

import commands 

commands.getoutput("whoami") 

आउटपुट:

'bganesan'

+3

बहुत आसान है, लेकिन मॉड्यूल अब बहिष्कृत है। –

1

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

#!/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` 
+3

आपको शायद यह नहीं करना चाहिए * – ThorSummoner

4

अजगर 3.5 से आगे, सुझाया गया तरीका subprocess.run उपयोग करने के लिए है। समान व्यवहार आपके द्वारा बताई गई के रूप में पाने के लिए आपको प्रयोग करेंगे:

output = subprocess.run("ls", shell=True, stdout=subprocess.PIPE).stdout 

यह एक bytes वस्तु वापस आ जाएगी। str प्राप्त करने के लिए आप .decode("ascii") या .decode("utf-8") को अंत में जोड़ना चाहेंगे।

संबंधित मुद्दे