2012-07-24 21 views
6

मैं पर्ल से मनमाने ढंग से पाइपलाइनों को स्थापित करने की कोशिश कर रहा हूं, जैसा कि शेल हो सकता है।पर्ल पाइपलाइन से "कम" चल रहा है

यह है वांछित प्रभाव है, यह की तरह है "गूंज foo | sed एस/ऊ/ए आर /":

#!/usr/bin/perl 
use strict; 

use IO::Handle; 

$| = 1; 

my ($first_prog, $second_prog) = ([qw(echo foo)], [qw(sed s/oo/ar/)]); 
#$second_prog = ["less"]; 

pipe(my $second_prog_input, my $first_prog_output) 
    or die "problem setting up pipe: $!\n"; 

if (fork) { 
    STDOUT->fdopen(fileno($first_prog_output), 'w') or die; 
    exec(@$first_prog) or die; 
} 
else { 
    STDIN->fdopen(fileno($second_prog_input), 'r') or die; 
    exec(@$second_prog) or 
     die "couldn't exec: $!: command was @$first_prog\n"; 
} 
हालांकि

, जब मैं दूसरा तर्क बनाने के "कम", मेरे टर्मिनल चमक, और मैं पेजर में आउटपुट नहीं देखें। संक्षिप्त फ्लैश के अलावा, कम चलने का कोई संकेत नहीं है।

अब कुछ मैं बिल्कुल भी नहीं मिलता है कि निम्नलिखित की तरह व्यवहार करता है "गूंज foo | कम":

pipe(my $first_prog_output, STDIN) or die "problem setting up pipe: $!\n"; 

my ($first_prog, $second_prog) = ([qw(echo foo)], ["less"]); 

open($first_prog_output, "-|", @$first_prog) or 
    die "$!: command was @$first_prog\n"; 

exec(@$second_prog) or 
    die "couldn't exec: $!: command was @$first_prog\n"; 

लेकिन मैं बिल्कुल समझ में नहीं आता क्या है कि कॉल करने के लिए पाइप() है करते हुए। पहला तर्क "पाठक" होना चाहिए, और दूसरा एक "लेखक" होना चाहिए। एसटीडीआईएन एक "लेखक" कैसे है?

मैं इन सब से बहुत उलझन में हूं, और लगता है कि अंतर्निहित यूनिक्स एपीआई के बारे में कुछ मौलिक हो सकता है जो मैं याद कर रहा हूं या मैं भूल गया हूं।

उत्तर

6

यह एक दिलचस्प समय मुद्दा है:

  • शैल कांटे, एक प्रक्रिया समूह बनाता है, यह करने के लिए टर्मिनल अग्रभूमि समूह करता है और अधिकारियों perl
  • perl कांटे और निष्पादन less
  • perl निष्पादन echo
  • echo बाहर निकलता है, खोल का मानना ​​है कि नौकरी की जाती है और एक बार फिर टर्मिनल अग्रभूमि प्रक्रिया समूह के रूप में खुद को सेट करती है।
  • less टर्मिनल प्राप्त करने का प्रयास करता है। यह टर्मिनल अग्रभूमि प्रक्रिया समूह में नहीं है। less विफल रहता है।

सरल समाधान: परिवर्तन fork!fork करने के लिए (या समतुल्य अपने if और else ब्लॉक स्वैप)। इस तरह, पाइपलाइन का अंतिम चरण नौकरी के जीवनकाल को परिभाषित करता है। (यदि आप ध्यान से देखते हैं, तो शेल कांटे और निष्पादन उसी क्रम में प्रक्रिया करते हैं जब यह पाइपलाइन चलाता है।)

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