|
程序目的是将一个输入导向一个本地的perl脚本, 再将这个脚本执行结果返回到当前的脚本, 使用open2双向管道操作, 但是总是不能成功, 请各位大大看看:
问题好像是本地脚本XXX.pl执行有问题, 因为是双向通信, 在IO上使用异步通信, select+sysread实现非阻塞的管道读取.
代码1, 主脚本代码:- #!/usr/bin/perl -w
- use strict;
- BEGIN {
- push(@INC, ".");
- }
- use FileHandle;
- use IPC::Open2;
- my %test_h = ();
- sub test {
- my $in;
- my $out;
- #my $pid = open2($in, $out, "cat " );
- my $pwd = `pwd`;
- chomp($pwd);
- my $pid = open2($test_h{"in"}, $test_h{"out"}, "./XXX1.pl" );
- printf STDOUT ("%x %d %x %d\n", $test_h{"in"}, fileno($test_h{"in"}), $test_h{"out"}, fileno($test_h{"out"}));
- while(1) {
- my $out = $test_h{"out"};
- printf $out ("%s", "stuff\n"); #先向管道中输入一些字符串.
- printf $out ("stuff\n");
- my $in = $test_h{"in"};
- #my $got = <$in>;
- #my $got = <{$test_h{"in"}}>;
- #printf STDOUT ("WE GET: %s\n", $got);
- my ($eof, @lines) = &nonblockGetLines($in); #尝试从管道中进行读取,
- if($eof) { last; }
- foreach my $line (@lines) {
- printf STDOUT ("GOT: %s\n", $line);
- }
- sleep(1);
- }
- }
- # Returns: ($eof,@lines)
- my %nonblockGetLines_last;
- sub nonblockGetLines {
- my $fh = $_[0];
- my $rfd = '';
- $nonblockGetLines_last{$fh} = ''
- unless defined $nonblockGetLines_last{$fh};
- #set file handle bit mask
- vec($rfd, fileno($fh), 1) = 1;
- #if something's coming
- my $out_fd = 0;
- if (not select($out_fd=$rfd, undef, undef, 0)>=0 )
- {
- printf STDERR ("%x select not ready.\n", $fh);
- return (0);
- }
- printf STDERR ("OUT_FD:%x IN_FD:%x fileno: %d \n", ord($out_fd), ord($rfd), fileno($fh));
-
- ## ## ## ## ## ## ## ## ##
- # 使用select+sysread进行nonblock的管道读取.
- #
- # 这里$out_fd总是0, 即是说西面的XXX.pl没有print任何东西.
- ## ## ## ## ## ## ## ## ##
- if(not vec($out_fd, fileno($fh), 1)) {
- printf STDERR ("%x not this one.\n", $fh);
- return (0);
- }
- my $buf = '';
- my $n = sysread($fh, $buf, 1024*1024, 0);
- if ( ! defined $n ) {
- #on error, we just print an error message
- printf STDERR ("MAPPER: %x got a read error at input line.\n", $fh);
- }elsif($n == 0) {
- # If we're done, make sure to send the last unfinished line
- return (1,$nonblockGetLines_last{$fh});
- }
- # Prepend the last unfinished line
- $buf = $nonblockGetLines_last{$fh}.$buf;
- # And save any newly unfinished lines
- if(substr($buf,-1) !~ /[\r\n]/ && $buf =~ s/([^\r\n]*)$//) {
- $nonblockGetLines_last{$fh} = $1;
- } else {
- $nonblockGetLines_last{$fh} = '';
- }
- return $buf ? (0,split(/\n/,$buf)) : (0);
- }
- &test();
复制代码
脚本2: 被调用的本地脚本XXX1.pl:- #!/usr/bin/perl -w
- #
- while(<STDIN>) { ###echo接收到的字符串
- print "M2\t", $_;
- }
复制代码 |
|