2012-03-09 16 views
7

में पाइप से unbuffered डेटा पढ़ें मैं पर्ल में एक पाइप से unbufferd डेटा पढ़ने की कोशिश कर रहा हूँ। उदाहरण के लिए नीचे दिए गए कार्यक्रम में:पर्ल

open FILE,"-|","iostat -dx 10 5"; 
$old=select FILE; 
$|=1; 
select $old; 
$|=1; 

foreach $i (<FILE>) { 
    print "GOT: $i\n"; 
} 

iostat प्रत्येक 10 सेकंड (पांच बार) डेटा को थूकता है। आप इस कार्यक्रम को ऐसा करने की उम्मीद करेंगे। हालांकि, इसके बजाय यह 50 सेकंड (यानी 10x5) के लिए लटका हुआ प्रतीत होता है, जिसके बाद यह सभी डेटा निकाल देता है।

ईओएफ के लिए सभी तरह के इंतजार किए बिना, जो भी डेटा उपलब्ध है (बिना छेड़छाड़ में) वापस लौटने के लिए मैं कैसे प्राप्त कर सकता हूं?

पीएस मैंने विंडोज के तहत इसके कई संदर्भ देखे हैं - मैं इसे लिनक्स के तहत कर रहा हूं।

+4

आपको 'fore' 'का उपयोग नहीं करना चाहिए। और आपका आउटपुट बफरिंग असीमित है, यह देखते हुए कि यह एक इनपुट हैंडल आउटपुट हैंडल नहीं है। – tchrist

+0

समय और foreach का उपयोग करते समय क्या अंतर है? – Jean

+0

@alertjean: 'foreach my $ i () {...}' में, फ़ाइल पढ़ने को संदर्भ संदर्भ में किया जाता है, यानी, 'foreach' लूप में लाइनों को संसाधित करने से पहले पूरी फ़ाइल पढ़ी जाती है। 'जबकि (मेरा $ i = ) {...} ', पढ़ा स्केलर संदर्भ में किया जाता है, यानी, प्रत्येक पंक्ति को पढ़ा जाता है और फिर अगली पंक्ति पढ़ने से पहले, जबकि ब्लॉक में संसाधित किया जाता है। –

उत्तर

5
#!/usr/bin/env perl 

use strict; 
use warnings; 



open(PIPE, "iostat -dx 10 1 |")  || die "couldn't start pipe: $!"; 

while (my $line = <PIPE>) { 
    print "Got line number $. from pipe: $line"; 
} 

close(PIPE)       || die "couldn't close pipe: $! $?"; 
+1

यह STDOUT ऑटोफ्लश – Jean

+0

को सक्षम किए बिना भी काम करता है यह उदाहरण perldoc रीडलाइन में है। –

1

यदि लिनक्स कमांड पर आपकी पर्ल स्क्रिप्ट में प्रतीक्षा करना ठीक है, तो यह काम करना चाहिए। मुझे नहीं लगता कि कमांड निष्पादन पूरा होने से पहले लिनक्स पर्ल स्क्रिप्ट पर नियंत्रण देगा।

#!/usr/bin/perl -w 
my $j=0; 
while($j!=5) 
{ 
    open FILE,"-|","iostat -dx 10 1"; 
    $old=select FILE; 
    $|=1; 
    select $old; 
    $|=1; 

    foreach $i (<FILE>) 
    { 
     print "GOT: $i"; 
    } 
    $j++; 
    sleep(5); 
} 
+6

** '$ |' सेट करना केवल आउटपुट बफरिंग को प्रभावित करता है। ** आप इस तरह के अन्य प्रोग्राम के आउटपुट बफरिंग को प्रभावित नहीं कर सकते हैं। इसके अलावा 'खुले (पाइपहेन्डल, "iostat -dx 10 1 |") के बजाय अजीब खुले के साथ क्या है मरना "पाइप शुरू नहीं कर सकता"; '? मैं कभी याद नहीं कर सकता '' | - '' बनाम '' - | "'खुद। वैसे भी, यदि 'iostat' प्रोग्राम एक पाइप पर अपने बफर को फ्लश नहीं कर रहा है, तो आपको ptys पर जाना होगा, जो एक वास्तविक परेशानी है लेकिन अपरिहार्य है। – tchrist

1

मैं unbuffering (विंडोज ActiveState Perl 5.10) के लिए मुझे

#!/usr/bin/perl 
use strict; 
use warnings; 
open FILE,"-|","iostat -dx 10 5"; 

while (my $old=<FILE>) 
{ 
    print "GOT: $old\n"; 
} 
+0

क्यों नहीं खोलें (फ़ाइल, "iostat -dx 10 5 |") '? – tchrist

+0

@tchist क्योंकि 'खुला पाइप,' - | ',' iostat ',' -dx ', 10, 5' या $ die! – larelogio

1

समाधान अब तक संबंध मेरे लिए काम नहीं किया के लिए काम कर कोड के नीचे है।

http://perldoc.perl.org/PerlIO.html के अनुसार, "एक unbuffered स्ट्रीम प्राप्त करने के लिए खुली कॉल में एक unbuffered परत (उदा।: यूनिक्स) निर्दिष्ट करें:"।

तो

open(PIPE, '-|:unix', 'iostat -dx 10 1') or die "couldn't start pipe: $!"; 

while (my $line = <PIPE>) { 
    print "Got $line"; 
} 

close(PIPE); 

मेरे मामले में काम किया है।