次のコードを実行すると、最後のサーバーは印刷されません。スクリプトは最後の2番目の配列要素の後にハングします。ハンドル配列の最後の要素でハングするPerlパイプの子プロセスからの読み取り
$ ./get_stuck.pl
92 18196
93 27420
94 17635
95 10258
96 10831
サーバー「96」の後に「97」出力があるはず、まだ存在しない、とスクリプトはちょうど/はその時点で停止ハング:
my %readers;
my $command = "pgrep -f weblogic.Name";
foreach my $server(@servers) {
pipe($readers{$server},WRITER);
unless(my $pid = fork()) {
my $response = qx(ssh -q oracle\@$server "$command");
print WRITER $response;
exit();
}
}
foreach my $server (@servers) {
my $fh = $readers{$server};
my @procs = <$fh>;
chomp(@procs);
for my $proc (@procs) {
printf "%s\t%s\n", substr($server,8), $proc;
}
}
print "end\n";
出力は次のようです。私は、配列の代わりに文字列を使用するようにリーダー部を変更した場合
次のように:から複数の結果がある場合
foreach my $server (@servers) {
my $fh = $readers{$server};
my $procs = <$fh>;
printf "%s\n", $server;
}
が...その後、スクリプトは、しかし、「97」を含むすべてのサーバーを表示しますコマンドでは、これは最初の結果だけを出力します(改行を改行しているようです)。言い換えれば、コマンドが特定のサーバーに対して3つのプロセスIDを返す場合、最初のプロセスIDだけが出力されます。
なぜ配列を使用すると、最後の要素でスクリプトがハングするのですか?または、私は文字列をどのように使用するかもしれないか(あまり望ましくない)、すべての結果を取得しますか?
私は未書込みのWRITERも考えました。私はまだ、スカラーが '<$fh>'でそれをどう読むかわかりません...私はどこかでそれを逃していますか? – zdim
@zdimスカラーコンテキストでは、最初の行だけを取得します(または、OPの言葉では、 "*ただし、コマンドから複数の結果がある場合、改行で改行されたように見えます)*")、リストコンテキストはすべての行を読み込み、EOFに達するまでブロックする必要があります。 – melpomene
優秀!私はWRITERを閉じようとしましたが、 'unless'ステートメントの中でやっていました。私はあなたが示唆したように字句変数を使用するように自分のコードを更新しましたが、明快にするために明示的な 'close'文を含んでいます。あなたの助けをありがとう。チャンピオン。 – Stu