Perlで2重Whileのコードを作成していた時に、結構初歩的なトコでひっかかったので備忘。

While文の中で外部ファイルを読み込ませたWhileを入れる場合は、openをWhile文の中に入れる必要がある。

例として、以前作成したssh自動ログインを行うスクリプトを使用。
openをWhileの外に出した場合。

Sponsored Links

use Net::OpenSSH;
use Capture::Tiny ':all';
open(HOSTLIST_FILE, "< ".$$Argv[0]) or die("error :$!");
open(COMMANDLIST_FILE, "< ".$$Argv[1]) or die("error :$!");
while (my $Hostline = <HOSTLIST_FILE>){
next if ($Hostline =~ /^#/);
chomp($Hostline);
my @Strline = split(/,/,$Hostline);
print "\n";
print "HostName :".$Strline[0]."\n";
print "IPAddress:".$Strline[1]."\n";
print "UserName :".$Strline[2]."\n";
print "PassWord :".$Strline[3]."\n";
print "\n";
my $Ssh = Net::OpenSSH->new(
"$Strline[1]",
user => "$Strline[2]",
password => "$Strline[3]",
master_opts => [ -o => "StrictHostKeyChecking=no"] 
);
$Ssh->error and die "unable to connect to remote host: ". $Ssh->error;
while (my $Commandline = <commandlist_file>){
my ($Stdout, $Stderr, $Result) = tee sub {
$Ssh->system($Commandline);
}
}
}

上の例では5行目に中のWhile文(26行目〜)が使用する外部ファイルを開いている。
ただ、このコードでは中のWhile文が実行されるのは外のWhile文(7行目〜)の一度だけとなる。

もう気づいている人の方が多いと思うが、これは一度目の外のWhile文を実行する際にはファイルが頭から読み込まれているため、中のWhile文が正常に処理がされるんだけど、それ以降は文を読み込んだ後のため処理が行われないというもの。

そのため、外のWhile文の中に中のWhile文で使用する外部ファイルを読み込ませる必要がある。

修正すると以下のようになる。


Written by blacknon

インフラ系のSE。一時期はプログラマ。 仮想化とオープンソースに興味あり。一日中寝てたい今日このごろ。 スペインとかで働きたいなぁ…(シエスタがあるので)

Leave a Comment

メールアドレスが公開されることはありません。

*