異なるプラットフォームでいくつかの子プロセスを並行して実行しようとしています。親プロセスは、すべての子プロセスがそれぞれのプラットフォームで完了した後にのみ続行する必要があります。
問題は、フォークを使用して子プロセスで「exec」コマンドを実行すると、ほぼ瞬時に終了することです。また、出力に一貫性がありません。ほとんどの場合、ログには 1 行しか表示されません。
-bash-2.05b$ cat Agent.SOLSPARC
caught SIGTERM signal, cleaning up
また
-bash-2.05b$ cat Agent.SOLSPARC
Host: EBSO9SPC Login: esm2
場合によっては、余分な行がいくつかあり、最後に「シグナル 15 によって強制終了されました」というメッセージが表示されます。「exec」で使用するコマンドは、実際にはリモートボックスに接続してmakeコマンドを実行するスクリプトを呼び出します。テスト目的で、私は現在、SOLSPARC という 1 つのプラットフォームのみを渡しています。また、特定のプラットフォームでコマンドが終了したかどうかを知りたいだけです。
すべての引数を「exec」に正しく渡しているかどうかわからなかったので、(インターネット上のさまざまなリンクを参照した後) さまざまな組み合わせを試しましたが、役に立ちませんでした。重要な観察事項の 1 つは、strace を使用してこの問題をデバッグしたところ、コマンドが正常に機能したことです。Perldoc で、Unix プラットフォームでは exec が/bin/sh -cを使用しているのを見ましたが、他のプラットフォームでは異なります。exec と strace が異なるシェルを使用していることですか?
私のコードの関連部分は次のとおりです。
sub compile {
my %child_pids;
foreach $plat (0 .. $#plat_list) {
my $pid = fork;
# Didn't check the undef condition for child
if ($plat_list[$plat] eq "SOLSPARC") {
print "\nStarted Solaris build \n";
if ($pid == 0) {
print "Inside Child Process \n\n";
exec ( "${ROOT}/${REM_EXEC} -t 1200 -c \"make LANG=en_US distclean \" -b ${ROOT} -l Agent. $plat_list[$plat]" ) or die "exec failed";
} elsif ($pid > 0) {
$child_pids{"SOLSPARC"} = $pid;
}
} else {
print "\nStarted build for other platforms \n";
if ($pid == 0) {
print "Inside Child Process \n\n";
exec ( "${ROOT}/${REM_EXEC} -t 1200 -c \"make LANG=en_GB clean \" -b ${ROOT} -l Agent. $plat_list[$plat]" ) or die "exec failed";
} elsif ($pid > 0) {
$child_pids{"$plat_list[$plat]"} = $pid;
}
}
}
my %rev_child_pids = reverse %child_pids;
while ((my $kid = waitpid -1, WNOHANG) > 0) {
if ($rev_child_pids{$kid} eq "SOLSPARC") {
print "\nChild process completed for SOLARIS platform $rev_child_pids{$kid} \n";
print "Run some other command here \n";
} else {
print "\nChild process completed for other platform $rev_child_pids{$kid} \n";
print "No more commands to run \n";
}
}
}
助言がありますか?