2012-06-29 16 views
194

मैं Ubuntu पर eSpeak का उपयोग कर और एक अजगर 2.7 स्क्रिप्ट कि प्रिंट है और संदेश बोलता हूँ में उपप्रक्रिया के उत्पादन को छिपाने के लिए कैसे:अजगर 2.7

import subprocess 
text = 'Hello World.' 
print text 
subprocess.call(['espeak', text]) 

eSpeak वांछित स्वर उत्पन्न करते हैं, लेकिन clutters खोल के साथ कुछ त्रुटियां (ALSA lib ..., कोई सॉकेट कनेक्ट नहीं है) इसलिए मैं आसानी से पढ़ा नहीं जा सकता था जिसे पहले मुद्रित किया गया था। बाहर निकलें कोड 0

दुर्भाग्य से इसकी क्रियापदता को बंद करने के लिए कोई दस्तावेज विकल्प नहीं है, इसलिए मैं इसे केवल चुपचाप चुप्पी करने और आगे की बातचीत के लिए खुले खोल को साफ रखने का एक तरीका ढूंढ रहा हूं।

मैं यह कैसे कर सकता हूं?

+0

क्या आप ओएससिस्टम के साथ बस कॉल नहीं कर सकते? आदर्श नहीं है लेकिन प्रिंट नहीं करना चाहिए मुझे लगता है कि –

+0

@ जोरनबीस्ले: ओएससिस्टम() कंसोल पर प्रिंट करेगा जब तक कि आप शेल कमांड – jdi

+0

संख्या, ओएससिस्टम ('espeak' + text) को इस व्यवहार को पुन: उत्पन्न नहीं करते हैं। – ferkulat

उत्तर

292

उत्पादन पुन: निर्देशित DEVNULL रहे हैं:

import os 
import subprocess 

FNULL = open(os.devnull, 'w') 
retcode = subprocess.call(['echo', 'foo'], stdout=FNULL, stderr=subprocess.STDOUT) 

इसे प्रभावी ढंग से इस शेल कमांड चल रूप में ही है:

retcode = os.system("echo 'foo' &> /dev/null") 
+40

सूक्ष्म साफ-सुथरा चुनौतियां: यदि आप 'subprocess.DEVNULL' उपलब्ध नहीं हैं (<3.3), तो' os.devnull' का उपयोग कर सकते हैं (<3.3), 'कॉल() 'के बजाय' check_call() 'का उपयोग करें, यदि आप अपना लौटा कोड नहीं देखते हैं, 'stdin/stdout/stderr' के लिए बाइनरी मोड में खुली फ़ाइलें,' os.system() 'के उपयोग को निराश किया जाना चाहिए,' &> 'उबंटू पर' sh' के लिए काम नहीं करता है एक स्पष्ट '>/dev/null 2 > और 1' का उपयोग किया जा सकता है। – jfs

+0

@ जेएफ। सेबेस्टियन: सुझावों के लिए धन्यवाद। मैं वास्तव में 'os.devnull' का उपयोग करना चाहता था लेकिन गलती से इसे बाहर टाइप किया। इसके अलावा, मैं 'कॉल' के ओपी उपयोग के साथ चिपक रहा हूं क्योंकि वे संभावित अपवाद नहीं देख रहे हैं 'चेककॉल' उठाएगा। और 'ओएस सिस्टम' रीडायरेक्ट के लिए, यह केवल एक उदाहरण था कि उपप्रोसेस दृष्टिकोण का प्रभावी उपयोग क्या कर रहा है। वास्तव में एक दूसरे सुझाव के रूप में नहीं। – jdi

+10

क्या आपने खोला गया एफएनयूएलएल बंद करने की आवश्यकता नहीं है? – Val

64

यहाँ एक अधिक पोर्टेबल संस्करण (सिर्फ मनोरंजन के लिए है, यह में आवश्यक नहीं है आपका मामला):

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
from subprocess import Popen, PIPE, STDOUT 

try: 
    from subprocess import DEVNULL # py3k 
except ImportError: 
    import os 
    DEVNULL = open(os.devnull, 'wb') 

text = u"René Descartes" 
p = Popen(['espeak', '-b', '1'], stdin=PIPE, stdout=DEVNULL, stderr=STDOUT) 
p.communicate(text.encode('utf-8')) 
assert p.returncode == 0 # use appropriate for your program error handling here 
+2

नोट करें कि यह एक 'DEVNULL' उत्पन्न करता है जो पूरी तरह से सामान्य नहीं है, जैसा कि 'subprocess' द्वारा प्रदान किया गया है; चूंकि यह 'wb' खोला गया है, इसका उपयोग 'stdin' के लिए नहीं किया जा सकता है। – Reid

+0

@ रीड: यदि आप इसके बजाय इसकी आवश्यकता है तो आप 'आर + बी' मोड का उपयोग कर सकते हैं। – jfs

-5

इसके बजाय आदेश.getoutput() का उपयोग क्यों नहीं करें?

import commands 

text = "Mario Balotelli" 
output = 'espeak "%s"' % text 
print text 
a = commands.getoutput(output) 
+0

ए) यह इनपुट को त्याग नहीं करता है, यह इसे अनावश्यक रूप से स्मृति में जमा करता है b) यदि टेक्स्ट में 'टेक्स्ट' उद्धरण है, या एक कम वर्ण एन्कोडिंग का उपयोग करता है, या कमांड लाइन के लिए बहुत बड़ा होता है तो यह तोड़ता है c) यह केवल यूनिक्स है (पायथन 2) – jfs

18

उपयोग subprocess.check_output (अजगर 2.7 में नया)। यह स्टडआउट दबाएगा और कमांड विफल होने पर अपवाद उठाएगा। (यह वास्तव में, stdout की सामग्री देता है ताकि आप कि बाद में उपयोग कर सकते हैं अपने कार्यक्रम में अगर आप चाहते हैं।) उदाहरण:

import subprocess 
try: 
    subprocess.check_output(['espeak', text]) 
except subprocess.CalledProcessError: 
    # Do something 

तुम भी साथ stderr को दबाने कर सकते हैं:

subprocess.check_output(["espeak", text], stderr=subprocess.STDOUT) 

पहले की तुलना में 2.7 के लिए ,

import os 
import subprocess 
with open(os.devnull, 'w') as FNULL: 
    try: 
     subprocess._check_call(['espeak', text], stdout=FNULL) 
    except subprocess.CalledProcessError: 
     # Do something 

यहाँ का उपयोग करें, आप

 subprocess._check_call(['espeak', text], stdout=FNULL, stderr=FNULL) 
साथ stderr को दबाने कर सकते हैं
+0

अधिक सटीक, यह stdout देता है। जो भी महान है, उतना ही अच्छा है जितना इसे अनदेखा करने में सक्षम होने के अलावा। –

+0

हालांकि, यह मानक त्रुटियों को मुखौटा नहीं करता है। – SmallChess

+0

मुझे लगता है कि यह अधिक सरल है। @StudentT मुझे लगता है कि आपको CalledProcessError के साथ त्रुटियों को संभालना चाहिए। 'subprocess.CalledProcessError को e' के रूप में छोड़कर और फिर 'e.code' या' e.output' –

0

यदि आप पाइथन 2.7x के साथ विंडोज़ में उपप्रोसेस मॉड्यूल (इस प्रश्न के लिए विशिष्ट नहीं हैं लेकिन मिलान शीर्षक) का उपयोग करते हैं और यह केवल त्रुटियां हैं जिन्हें आप दबाना चाहते हैं (इस प्रश्न के लिए विशिष्ट), तो आप कुछ ऐसा कर सकते हैं इस:

output = subprocess.check_output(["arp", "-a", "-N", "127.0.0.2"], stderr=subprocess.STDOUT)

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

+1

का उपयोग करें जो त्रुटियों को दबा नहीं देता है। यह stderr को stdout पर रीडायरेक्ट करता है, इसलिए 'आउटपुट' ने आउटपुट और त्रुटियों को दबा दिया है, जो शायद वांछित नहीं है। –

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