Perl 在派生的流程中,如何期望退出无限循环

Perl 在派生的流程中,如何期望退出无限循环,perl,expect.pm,Perl,Expect.pm,让我举一个具体的例子来问这个问题。第一个代码nlines.pl如下所示: #!/usr/local/bin/perl ######################### # print Hello world n times with n entered by a prompt ######################### use strict; use Time::HiRes qw(sleep); die "Syntax: $0 <prompt> <time2sle

让我举一个具体的例子来问这个问题。第一个代码nlines.pl如下所示:

#!/usr/local/bin/perl
#########################
# print Hello world n times with n entered by a prompt
#########################

use strict;
use Time::HiRes qw(sleep);

die "Syntax: $0 <prompt> <time2sleep>\n" if ($#ARGV < 1);
my $prompt = $ARGV[0] . '> ';
my $sleepsec = $ARGV[1];        print "$0: Timeout interval: $sleepsec\n";
print $prompt;
while (<STDIN>) {
        chomp;
        last unless /\d+/;
        my $loopCount = $_;
        print "\n$0: Received request for $loopCount lines\n";
        for (my $count = 0; $count != $loopCount ; $count++) {
                Time::HiRes::sleep($sleepsec) if ($sleepsec > 0);
                print "$0 [$count] Hello world\n"
        }
        print $prompt
}
print "Bye bye\n";
exit 0;
#/usr/local/bin/perl
#########################
#打印Hello world n次,提示输入n
#########################
严格使用;
使用时间:雇佣qw(睡眠);
die“语法:$0\n”if($#ARGV<1);
my$prompt=$ARGV[0].>';
my$sleepsec=$ARGV[1];打印“$0:超时间隔:$sleepsec\n”;
打印$prompt;
而(){
咀嚼;
最后一个,除非/\d+/;
我的$loopCount=$\;
打印“\n$0:收到$loopCount行的请求\n”;
对于(我的$count=0;$count!=$loopCount;$count++){
时间::雇佣::睡眠($sleepsec)如果($sleepsec>0);
打印“$0[$count]Hello world\n”
}
打印$prompt
}
打印“再见”\n;
出口0;
$nlines.pl pp 0.2生成一个提示“pp>”,当输入“6”时,以0.2秒的时间间隔打印“Hello world”6次(仅当间隔为+ve number时)。非数字输入可以使您脱离循环,而行计数为负数将导致无限循环。很好

现在,考虑第二个脚本“ExpReal.PL”,作为上面脚本的驱动程序。

#!/usr/local/bin/perl
#############################
# expnlines.pl: driver for nlines.pl
#############################

use strict;
use Expect;

die "Syntax: $0 <Count> <SleepSec>\n" if ($#ARGV < 1);
my $count = $ARGV[0];
my $child = 'nlines.pl';
my $prompt = 'CountOfLines';
my $ex = Expect->new;
$ex->raw_pty(1);
$ex->spawn ($child, $prompt, $ARGV[1]);
$ex->expect (1, $prompt) or die "$0: No prompt from $child\n";
print "$0: Sending $count\n";
$ex->send($count . "\n");
$ex->expect (2, $prompt) or die "\n$0: Expect timed out for $count\n";
print "\n$0: Received prompt back from expect\n";
exit 0;
#/usr/local/bin/perl
#############################
#expnlines.pl:nlines.pl的驱动程序
#############################
严格使用;
使用Expect;
die“语法:$0\n”if($#ARGV<1);
我的$count=$ARGV[0];
my$child='nlines.pl';
my$prompt='countofline';
我的$ex=期望->新;
$ex->raw_pty(1);
$ex->spawn($child,$prompt,$ARGV[1]);
$ex->expect(1,$prompt)或die“$0:No prompt from$child\n”;
打印“$0:发送$count\n”;
$ex->send($count.“\n”);
$ex->expect(2,$prompt)或die“\n$0:expect为$count超时\n”;
打印“\n$0:从expect收到提示\n”;
出口0;
如果我们以“expnlines.pl 4 0.2”的形式运行它,它就可以正常工作。“expnlines.pl-10.3”(或超时的其他任何内容)也可以使用。对于-ve#For linecount,第一个脚本进入无限循环,但由expect超时。但是,“expnlines.pl-10”无法停止无限循环(在这2秒之后),我也无法弄清楚如何让expect中断这个循环

有什么建议吗?蒂亚


顺便说一句,在我的现实世界中,我无法控制“nlines.pl”的二进制等价物。我的脚本是“expnlines.pl”,我使用expect作为二进制文件的驱动程序,带有不同的参数。当子进程运行无限循环时,我需要某种机制来检测和停止它,但我不知道如何进行。感谢您的响应。

超时后,您可以使用
硬关闭(
软关闭
,如果您需要友好,可以等待它使用的额外时间)来关闭命令,以终止它和无限循环

而不是

$ex->expect (2, $prompt) or die "\n$0: Expect timed out for $count\n";
你可以这样做

if (!$ex->expect(2, $prompt)) {
    print "\n$0: Expect timed out for $count, closing\n";
    $ex->hard_close();
}
else {
    print "\n$0: Received prompt back from expect\n";
}

试过你的改变,对我不起作用。问题是,我们永远无法到达你的第二线。不知道这是否是由于操作系统、Perl/Expect版本等造成的。我使用的是OSX El Capitan v10.11.3、Perl 5.22.1、Expect 1.320.00。如果解决方案适合您,您是否介意共享您的平台和/或版本。谢谢。OSX 10.10.5、Perl 5.20.1和Expect 1.32。这对我有用。