2009-03-30 20 views
44

मेरे पास A नामक एक बाइनरी है जो कॉल करते समय आउटपुट उत्पन्न करती है। अगर मैं इसे बैश खोल से बुलाता हूं, तो अधिकांश आउटपुट A > /dev/null द्वारा दबाया जाता है। सभी आउटपुट A &> /dev/nullपाइथन में आउटपुट आउटपुट निष्पादन योग्यों को कॉल करता है

पर दबाया गया है मेरे पास B नामक एक पाइथन लिपि है जिसे A पर कॉल करने की आवश्यकता है। से सभी आउटपुट दबाने के दौरान, मैं B से आउटपुट उत्पन्न करने में सक्षम होना चाहता हूं।

B के भीतर से

, मैं os.system('A'), os.system('A > /dev/null'), और os.system('A &> /dev/null'), os.execvp('...'), आदि की कोशिश की है, लेकिन उन में से कोई भी मैं B &> /dev/null चला सकते हैं ए

से सभी उत्पादन को दबाने, लेकिन उस को दबा B के सभी ' एस आउटपुट भी है और मुझे वह नहीं चाहिए।

किसी के पास कोई सुझाव है?

उत्तर

57

आप अजगर 2.4 है, तो आप the subprocess module उपयोग कर सकते हैं: आदेश किसी भी तर्क नहीं है

>>> import subprocess 
>>> s = subprocess.Popen(['cowsay', 'hello'], \ 
     stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0] 
>>> print s 
_______ 
<hello> 
------- 
     \ ^__^ 
     \ (oo)\_______ 
      (__)\  )\/\ 
       ||----w | 
       ||  || 
+0

मैंने कोशिश की और यह काम किया, धन्यवाद! – Lin

+57

गाय के लिए +1 :) – MestreLion

+7

यह स्टडआउट आउटपुट असंबद्ध होने पर खराब प्रदर्शन करेगा। –

8

os.system() दस्तावेज़ों का उल्लेख करते हुए, subprocess मॉड्यूल का उपयोग करें, और यदि आप चाहें, तो stdout = open (os.devnull, 'w') सेट करें (और शायद stderr के लिए वही) जब आप खोलें उपप्रक्रिया।

103
import os 
import subprocess 

command = ["executable", "argument_1", "argument_2"] 

with open(os.devnull, "w") as fnull: 
    result = subprocess.call(command, stdout = fnull, stderr = fnull) 

हैं, तो आप सिर्फ यह एक साधारण स्ट्रिंग के रूप में प्रदान कर सकते हैं।

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

+0

शैल = सही क्यों है? –

+4

क्योंकि मूल प्रश्न os.system का उपयोग करता था और, यह नहीं जानता कि वह क्या कर रहा है, shell = True इसके लिए सबसे विश्वसनीय अनुवाद है। – DNS

+0

डीएनएस, मैंने आपके समाधान की कोशिश की और यह मेरे लिए पूरी तरह से काम करता है। धन्यवाद! – Lin

1

मुझे पता है कि यह खेल के लिए देर हो चुकी है, लेकिन ओएससिस्टम के भीतर आउटपुट को/dev/null पर रीडायरेक्ट क्यों न करें? उदा .:

tgt_file = "./bogus.txt" 
os.sytem("d2u '%s' &> /dev/null" % tgt_file) 

यह उन अवसरों के लिए काम करने के लिए जब आप subprocess.STDOUT से निपटने के लिए नहीं करना चाहते हैं लगता है।

+2

क्योंकि सिस्टम कॉल के लिए os.system का उपयोग बहिष्कृत किया गया है। उपप्रोसेस मॉड्यूल एक बहुत अधिक सुरुचिपूर्ण और सुरक्षित तरीके से संभालते हैं – MestreLion

12

यदि आपका खोज इंजन आपको इस पुराने प्रश्न (मेरे जैसा) ले जाता है, तो ध्यान रखें कि पीआईपीई का उपयोग करके डेडलॉक्स हो सकता है। वास्तव में, क्योंकि पाइप buffered हैं, आप एक पाइप में बाइट्स की एक निश्चित संख्या लिख ​​सकते हैं, भले ही कोई इसे पढ़ न सके। हालांकि बफर का आकार सीमित है। और इसके परिणामस्वरूप यदि आपके प्रोग्राम ए में बफर से बड़ा उत्पादन होता है, तो ए को लेखन पर अवरुद्ध कर दिया जाएगा, जबकि कॉलिंग प्रोग्राम बी ए की समाप्ति का इंतजार कर रहा है लेकिन नहीं, इस विशेष मामले में ... नीचे टिप्पणियां देखें।

फिर भी, मैं डेविन जीनपीयर और डीएनएस समाधान का उपयोग करने की सलाह देता हूं।

+0

क्या यह वाकई सच है? मुझे लगता है कि अगर आप कॉल() या popen()/प्रतीक्षा() का उपयोग करते हैं, लेकिन पॉपन()/संचार() नहीं करते हैं तो यह केवल deadlocks है। –

+0

हां! दस्तावेज़ को उद्धृत करने के लिए, "नोट डेटा को पढ़ने में स्मृति में buffered है, इसलिए डेटा आकार बड़ा या असीमित है, तो इस विधि का उपयोग न करें।" –

+0

"स्मृति में buffered" का मतलब यह नहीं है कि पाइप deadlocked है। वे दस्तावेज़ों में जो समस्या का उल्लेख करते हैं वह यह है कि यदि कोई आदेश बहुत अधिक उत्पादन उत्पन्न करता है, तो यह सब पाइथन के ढेर पर स्मृति में संग्रहीत हो जाता है। यह निश्चित रूप से अवांछनीय है, और स्मृति त्रुटियों से बाहर हो सकता है या बहुत बुरी तरह से प्रदर्शन कर सकता है, लेकिन केवल चरम मामलों में और आपको डेडलॉक्स का अनुभव नहीं होगा। – Clueless

0

मैं का उपयोग करें:

call(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE) 

जहां आदेश आदेश + तर्क

इसके लिए की स्ट्रिंग है काम करने के लिए आप उपप्रक्रिया आयात चाहिए

+1

क्या वह डेडलॉक नहीं होगा? –

0

तुम सिर्फ STDOUT पर कब्जा करने की जरूरत है, नहीं करता है ' इसे एक चर के लिए असाइन करने के लिए यह करते हैं? उदाहरण के लिए:

megabyte='' 
# Create a 1 MiB string of NULL characters. 
for i in range(1048576): 
    megabyte += '\0' 
fh=open('zero.bin','w') 
# Write an 8 GiB file. 
for i in range(8192): 
    print(i) 
    # Suppress output of 'write()' by assigning to a variable. 
    discard=fh.write(megabyte) 
fh.close() 

मैं अपने हार्ड ड्राइव पर शून्य रिक्त स्थान के लिए एक बड़ा शून्य से भरे फ़ाइल बनाने गया था और पाया कि प्रत्येक कॉल handle.write लिए (स्ट्रिंग) लिखा बाइट की संख्या थूक से बाहर। आउटपुट को दबाने वाले एक वैरेबल को सौंपना।

21

पायथन 3.3 और उच्चतर में, subprocessan option for redirecting to /dev/null का समर्थन करता है। इसका उपयोग करने के लिए, .Popen और मित्रों को कॉल करते समय, कीवर्ड तर्क के रूप में stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, निर्दिष्ट करें। ,

subprocess.DEVNULL¶

विशेष मूल्य कि stdin के रूप में इस्तेमाल किया जा सकता:

तो डीएनएस का जवाब, अजगर 3.3+ के लिए फिर से लिखा,

import subprocess 
command = ["executable", "argument_1", "argument_2"] 
result = subprocess.call(command, 
         stdout=subprocess.DEVNULL, 
         stderr=subprocess.DEVNULL) 

प्रलेखन से हो जाता है stdout या stderr पॉपन के लिए तर्क और इंगित करता है कि विशेष फ़ाइल os.devnull का उपयोग किया जाएगा।

संस्करण 3.3 में नया।

पायथन 3.0 से 3.2 के लिए, आपको open(os.devnull) का उपयोग करके नल डिवाइस मैन्युअल रूप से खोलना होगा, जैसा कि DNS ने लिखा था।

+1

दुर्भाग्यवश, 'subprocess.DEVNULL' केवल 3.3+ में उपलब्ध है। इस उत्तर को संगतता कोड (या इसके संदर्भ में) के साथ संशोधित किया जाना चाहिए। 'Shell = True' का उपयोग करने का कोई कारण नहीं है। – phihag

+0

@ एफहाग: मैंने संगतता कोड शामिल नहीं किया क्योंकि DNS का उत्तर पर्याप्त रूप से वर्णन करता है कि इसे 'subprocess.DEVNULL' के बिना कैसे किया जाए। आप 'खोल' के बारे में सही हैं; तय की। –

+0

यह वह है जो मेरे लिए काम करता है, पायथन 3 का उपयोग कर –

0

यदि आप पूरा करने के लिए आदेश का इंतजार नहीं करना चाहते हैं, जैसे कि बैकअप कार्य शुरू करना, दूसरा विकल्प बैश के माध्यम से इसे पास करना है, जिससे रीडायरेक्ट सामान्य रूप से संचालित हो जाता है।

उदाहरण के लिए

, एक ध्वनि फ़ाइल aplay का उपयोग कर शुरू कर:

import os 

def PlaySound(filename): 
    command = 'bash -c "aplay %s &> /dev/null &"' % (filename) 
    os.system(command) 

इस तरह से मैं एक नई प्रक्रिया अंडे सकते हैं, यह खत्म हो और टर्मिनल के लिए मुद्रण से इसे रोकने के लिए के लिए इंतजार नहीं कर। एकमात्र पकड़ यह है कि यह एक बैश इंस्टेंस के साथ-साथ आप जिस प्रक्रिया को चला रहे हैं, उसे थोड़ा ओवरहेड प्रदान करेगा।

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