2010-03-01 12 views
6

मैं पाइथन के सबप्रोसेस का उपयोग कर रहा हूं। मेजबान ऑपरेटिंग सिस्टम के बाइनरी क्लाइंट का उपयोग करके कुछ एफ़टीपी करने के लिए खोलें। मैं विभिन्न कारणों से ftplib या किसी अन्य पुस्तकालय का उपयोग नहीं कर सकता।subprocess.popen को stdin की आपूर्ति क्यों करता है जो बदलने के लिए stdout को लिखा जाता है?

यदि मैं पॉपिन इंस्टेंस में स्टडीन हैंडलर संलग्न करता हूं तो बाइनरी का व्यवहार बदलना प्रतीत होता है। उदाहरण के लिए, XP के FTP क्लाइंट है, जिससे समस्या को आदेशों की एक पाठ फ़ाइल को स्वीकार करता है का उपयोग करते हुए:

>>>from subprocess import Popen, PIPE 
>>>p = Popen(['ftp','-A','-s:commands.txt','example.com'], stdout=PIPE) 
>>>p.communicate()[0] 
'Connected to example.com. 
220 ProFTPD 1.3.1 Server (Debian) ... 
331 Anonymous login ok, send your complete email address as your password 
<snip> 
ftp> binary 
200 Type set to I 
ftp> get /testfiles/100.KiB 
200 PORT command successful 
150 Opening BINARY mode data connection for /testfiles/100.KiB (102400 bytes) 
226 Transfer complete 
ftp: 102400 bytes received in 0.28Seconds 365.71Kbytes/sec. 
ftp> quit 
>>> 

commands.txt:

binary 
get /testfiles/100.KiB 
quit 

जब भी stdin की आपूर्ति, तुम सब stdout में मिलता है:

>>>from subprocess import Popen, PIPE 
>>>p = Popen(['ftp','-A','-s:commands.txt','example.com'], stdin=PIPE, stdout=PIPE) 
>>>p.communicate()[0] 
'binary 
get /testfiles/100.KiB 
quit' 
>>> 

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

विंडोज़ में मैं stdin का उपयोग किए बिना प्रभावी रूप से स्क्रिप्ट ftp पर स्विच का उपयोग कर सकता हूं, लेकिन अन्य प्लेटफार्मों पर एक उस तरह की बातचीत के लिए खोल पर निर्भर करता है।

पाइथन संस्करण दोनों प्लेटफार्मों पर 2.6.x है। Stdin परिवर्तन stdout के लिए एक हैंडल की आपूर्ति क्यों करेगा, और सर्वर प्रतिक्रियाएं कहां चली गईं?

+0

क्या आपने 'ftplib' का उपयोग करने पर विचार किया है? http://docs.python.org/library/ftplib.html –

+0

आप किस कारण से ftplib का उपयोग नहीं कर सकते हैं। यह आपके पायथन वितरण के साथ आता है? – ghostdog74

उत्तर

4

मुझे लगता है कि मैंने कहीं पढ़ा है (लेकिन यह याद नहीं कर सकता) कि विंडोज़ एफटीपी क्लाइंट मूल बीएसडी कार्यान्वयन में से एक से आया है। इसमें यह निश्चित रूप से मैक ओएस एक्स के एफटीपी कार्यान्वयन के साथ कुछ रिश्ते साझा करेगा।

मेरे लिए, यह पॉपन से संबंधित नहीं है लेकिन क्लाइंट एफटीपी प्रोग्राम कार्यान्वयन के लिए है, जो इस संदर्भ के बारे में कुछ जांच करता है जिसमें यह लॉन्च किया गया है (यह देखने के लिए कि क्या यह मानव या शेल स्क्रिप्ट के साथ बातचीत कर रहा है), इसाटी का उपयोग करके (3) जैसा कि उनके जवाब में इग्नासिओ के साथ उल्लेख किया गया है। कार्यक्रमों के लिए यह सामान्य अभ्यास है जिसका उपयोग दोनों संदर्भों में किया जा सकता है। एक प्रसिद्ध उदाहरण है --color = auto विकल्प के लिए जीएनयू grep कार्यान्वयन: यह केवल आउटपुट रंगीन होगा अगर stdout एक tty है, और यदि grep का आउटपुट किसी अन्य कमांड में पाइप नहीं किया गया है।

+0

हाँ मुझे लगता है कि आप इसके बारे में सही हैं। जब मैं एक विंडोज सेवा के रूप में कार्य कोड चलाता हूं (जिसमें एक गैर-इंटरैक्टिव स्टडीन भी है) मुझे वही व्यवहार मिलता है। तो फॉलो-अप सवाल यह है कि क्या निष्पादन योग्य 'ट्रिकिंग' का एक क्रॉस-प्लेटफार्म तरीका है कि यह एक टीटी से बात कर रहा है? मुझे लगता है कि इसे पूर्ण आउटपुट का उत्पादन करने के लिए वास्तव में किसी टीटी की किसी विशेषताओं की आवश्यकता नहीं है। – Matt

+0

मुझे नहीं पता कि। हालांकि, ध्यान दें कि एक एकीकृत इंटरफ़ेस (यानी कमांड लाइन तर्क) के साथ कोई मानक क्रॉस प्लेटफ़ॉर्म ftp कमांड नहीं है, इसलिए आपको इस दृष्टिकोण के साथ पोर्टेबल कोड लिखने में कठिनाई होगी। अपनी स्क्रिप्ट केवल एफ़टीपी का उपयोग करके फ़ाइलें की एक जोड़ी डाउनलोड करने के लिए की जरूरत है, मैं urllib या urllib2 का उपयोग करना चाहिये: आयात urllib च = urllib.urlopen ('ftp://example.com/testfiles/100.KiB') डेटा = f.read() –

+0

मैंने कुछ समय पेक्सपेक्ट/वेक्सपेक्ट के साथ प्रयोग किया, जो एक उचित मंच स्वतंत्र समाधान होने का वादा किया।अफसोस की बात है कि एक कंसोल की आवश्यकता है और विंडोज सेवा के रूप में चलाने पर बहुत ही मर जाता है। – Matt

7

प्रोग्राम stdin पर tty की उपस्थिति का पता लगाने के लिए isatty(3) का उपयोग कर सकता है।

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