[英]How can expect get out of infinite loop in a spawned process
Let me ask the question with a specific set of example.让我用一组具体的例子来问这个问题。 The 1st code, nlines.pl is as follows:
第一个代码,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;
$ nlines.pl pp 0.2 generates a prompt "pp> ", and when given an input "6", prints "Hello world" 6 times, with 0.2 secs time intervals (only if the interval is +ve number). $ nlines.pl pp 0.2 生成提示“pp>”,当输入“6”时,打印“Hello world”6 次,时间间隔为0.2 秒(仅当间隔为+ve 数时)。 A non-numeric input gets you out of the loop, and a negative number for line count results in an infinite loop.
非数字输入使您脱离循环,而行数的负数会导致无限循环。 Works fine!
工作正常!
Now, consider the 2nd script - "expnlines.pl", as a driver for the script above.现在,考虑第二个脚本 - “expnlines.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;
If we run this as "expnlines.pl 4 0.2" it works fine.如果我们将其作为“expnlines.pl 4 0.2”运行,它工作正常。 "expnlines.pl -1 0.3" (or whatever else for the timeout) works too.
“expnlines.pl -1 0.3”(或其他超时时间)也有效。 For the -ve # for linecount, the 1st script enters into the infinite loop but is timed out by expect.
对于 linecount 的 -ve #,第一个脚本进入无限循环,但被expect 超时。 However, "expnlines.pl -1 0" cannot stop the infinite loop (after those 2 seconds), and I cannot figure out how to get expect to interrupt this loop.
但是,“expnlines.pl -1 0”无法停止无限循环(在那 2 秒之后),我无法弄清楚如何期望中断此循环。
Any suggestions?有什么建议? TIA.
TIA。
Btw, in my real world, I do not have any control over equivalent of the binary for "nlines.pl".顺便说一句,在我的现实世界中,我无法控制“nlines.pl”的二进制文件的等效项。 My script is "expnlines.pl", and I am using expect as a driver for the binary, with different arguments.
我的脚本是“expnlines.pl”,我使用 expect 作为二进制文件的驱动程序,具有不同的参数。 When the child process runs an infinite loop, I need some mechanism to detect and stop it, and I cannot figure out how.
当子进程运行无限循环时,我需要某种机制来检测和停止它,但我不知道如何进行。 Appreciate the responses.
欣赏回应。
After a timeout you can close the command with a hard_close
, (or a soft_close
if you need to be nice, and can wait the extra time it uses), to terminate it, and the infinite loop.超时后,您可以使用
hard_close
关闭命令(或者如果您需要使用soft_close
,并且可以等待它使用的额外时间)来终止它,以及无限循环。
Instead of代替
$ex->expect (2, $prompt) or die "\n$0: Expect timed out for $count\n";
You can do something like你可以做类似的事情
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";
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.