Pocket

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文で使用する外部ファイルを読み込ませる必要がある。

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

Pocket

Written by blacknon

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

Leave a Comment

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