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" を 0.2 秒間隔で 6 回出力します (間隔が +ve 数値の場合のみ)。数値以外の入力はループから抜け出し、行数に負の数を指定すると無限ループになります。正常に動作します!

ここで、2 番目のスクリプト「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 # の場合、最初のスクリプトは無限ループに入りますが、期待によりタイムアウトします。ただし、「expnlines.pl -1 0」は無限ループを停止できず (2 秒後)、このループを中断することを期待する方法がわかりません。

助言がありますか?ティア。

ところで、私の現実の世界では、「nlines.pl」のバイナリに相当するものを制御することはできません。私のスクリプトは「expnlines.pl」で、バイナリのドライバーとして異なる引数で期待を使用しています。子プロセスが無限ループを実行すると、それを検出して停止するメカニズムが必要ですが、その方法がわかりません。応答に感謝します。

4

1 に答える 1

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";
}
于 2016-03-17T06:38:47.040 に答える