2016-03-16 57 views
1

讓我用一組特定的例子來問這個問題。的第一代碼,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生成提示 「PP>」,並且當給定的輸入 「6」,輸出 「Hello World」 6次,用0.2秒的時間間隔(僅當間隔是+ ve數字時)。一個非數字輸入讓你走出循環,而一個負數的行數導致無限循環。工作正常!

現在,考慮第二個腳本 - 「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; 

如果我們將其作爲「expnlines.pl 4 0.2」運行,它可以正常工作。 「expnlines.pl -1 0.3」(或任何其他的超時)也可以。對於-ve#for linecount,第一個腳本進入無限循環但按期望超時。然而,「expnlines.pl -1 0」不能停止無限循環(在那些2秒後),並且我無法弄清楚如何期望中斷這個循環。

有什麼建議嗎? TIA。

順便說一下,在我的現實世界中,我對「nlines.pl」的二進制文件沒有任何控制權。我的腳本是「expnlines.pl」,我使用期望作爲驅動程序的二進制文件,具有不同的參數。當子進程運行一個無限循環時,我需要一些機制來檢測並阻止它,而我無法弄清楚如何。欣賞迴應。

回答

1

超時後,您可以使用hard_close(或soft_close,如果您需要很好,並且可以等待額外使用時間),終止命令和無限循環來關閉命令。

而不是

$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"; 
} 
+0

想你的變化,對我不起作用。問題 - 我們永遠不會進入第二線。想知道這是由於操作系統,Perl/Expect版本等。我在OSX El Capitan v10.11.3,Perl 5.22.1,期望1.320.0_0。如果解決方案適合您,您是否介意分享您的平臺和/或版本。謝謝。 –

+0

OSX 10.10.5,Perl 5.20.1和Expect 1.32。這對我有用。 – bolav