2010-04-28 10 views
6

मेरे पास एक छोटा कमांड लाइन उपकरण है जो stdin से पढ़ता है। कमांड लाइन मैं या तो चल पाएंगे पर ...क्या मैं पाइथन में पॉपन के साथ एक खुली gzip फ़ाइल का उपयोग कर सकता हूं?

./foo < bar 

या ...

cat bar | ./foo 

एक gziped फ़ाइल के साथ मैं अजगर में

zcat bar.gz | ./foo 

चला सकते हैं मैं कर सकता हूँ। ..

Popen(["./foo", ], stdin=open('bar'), stdout=PIPE, stderr=PIPE) 

लेकिन मैं

import gzip 
Popen(["./foo", ], stdin=gzip.open('bar'), stdout=PIPE, stderr=PIPE) 

मैं हवा को चलाने के लिए

p0 = Popen(["zcat", "bar"], stdout=PIPE, stderr=PIPE) 
Popen(["./foo", ], stdin=p0.stdout, stdout=PIPE, stderr=PIPE) 

मैं कुछ गलत कर रहा हूँ होने नहीं कर सकते? मैं gzip.open ('bar') का उपयोग पॉपन के लिए stdin arg के रूप में क्यों नहीं कर सकता?

उत्तर

4

क्योंकि उपप्रोसेस के 'stdin' और 'stdout' फ़ाइल डिस्क्रिप्टर (जो एक संख्या है) लेता है, जो एक ऑपरेटिंग सिस्टम संसाधन है। यह इस तथ्य से मुखौटा है कि यदि आप किसी ऑब्जेक्ट को पास करते हैं, तो सबप्रोसेस मॉड्यूल जांचता है कि ऑब्जेक्ट में 'fileno' विशेषता है और यदि उसके पास है, तो इसका उपयोग होगा।

'gzip' ऑब्जेक्ट कुछ ऑपरेटिंग सिस्टम प्रदान नहीं करता है। एक खुली फ़ाइल है, एक सॉकेट है, एक पाइप है। Gzip ऑब्जेक्ट एक ऑब्जेक्ट है जो पढ़ने() और लिखने() विधियों को प्रदान करता है लेकिन कोई fileno विशेषता नहीं है।

हालांकि आप सबप्रोसेस की संवाद() विधि को देख सकते हैं, तो आप इसका उपयोग करना चाहेंगे।

+0

हां, मैं वास्तव में पी = पॉपन ([...]) का उपयोग कर रहा हूं और फिर p.communicate() [0] पढ़ रहा हूं। इसके अलावा, मेरे प्रोग्राम को foo नहीं कहा जाता है और मेरी इनपुट फ़ाइल को बार नहीं कहा जाता है ;-) तो आप कह रहे हैं कि कोई आसान फ़िक्स नहीं है? मुझे यह अजीब लगता है कि पॉपन (["./ foo",], stdin = gzip.open ('bar'), stdout = pIPE, stderr = PIPE) काम करता है (हालांकि खराब आउटपुट लौटा रहा है) और कोई raise नहीं करता है अपवाद। यह इसके साथ कुछ कर रहा है भले ही इसमें एक फिलीनो विशेषता न हो। –

+0

उपप्रोसेसर मॉड्यूल से 'पीआईपीई' और 'STDOUT' विशेषताएँ 'विशेष स्थिरांक' हैं; stderr = STDOUT के मामले में, निरंतर कहते हैं कि क्लाइंट प्रक्रिया को पारित किया जाना चाहिए, जो कि stdout के रूप में पारित किया जाना चाहिए। पीआईपीई के मामले में, ऑपरेटिंग सिस्टम 'पाइप()' कमांड का उपयोग करके एक नया फिलेनो बनाया जाता है, पाइप का एक आधा (जो वास्तव में 2 नंबर है) क्लाइंट प्रक्रिया में पास किया जाता है और आपको एक दिया जाता है। जो कुछ भी एक हिस्से में लिखा जाता है, उसे दूसरे से पढ़ा जा सकता है। आप इसे आसान तरीके से ठीक नहीं कर सकते हैं, अधिक प्रोग्रामिंग की आवश्यकता होगी। – ondra

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

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