1

これはおそらくこれを行うための最良または最適な方法ではないことを認識していますが、以前にどこかでこれに遭遇したことがあり、答えに興味があります。

私は、実行され、時々死ぬinitから呼び出されるperlスクリプトを持っています。これをすばやくデバッグするために、基本的に

#$path set from library call.    
while(1){
  system("$path/command.pl " . join(" ",@ARGV) . " >>/var/log/outlog 2>&1");
  sleep 30; #Added this one later. See below...
}

コマンドラインからこれを起動すると、正常に動作し、期待どおりに動作します。command.pl が呼び出され、スクリプトは基本的にそこで停止し、子プロセスが停止してから再び実行されます。

ただし、起動スクリプトから (実際には start-stop-daemon を介して) 呼び出されると、システム コマンドはすぐに戻り、command.pl は実行されたままになります。その後、別の方向に進みます。そして何度も何度も。(これは sleep コマンドがないと楽しくありませんでした。) ps は、(多数の) command.pl の親が、ラッパー スクリプトの ID ではなく 1 であることを明らかにします (これは、コマンド ラインから実行した場合です)。

何が起こっているか知っている人はいますか?

4

3 に答える 3

2

正常command.plに実行されていない可能性があります。ファイルに実行権限がない可能性があります (言う必要がありますperl command.plか?)。考えていたディレクトリとは異なるディレクトリからコマンドを実行していて、command.plファイルが見つからない可能性があります。

確認できることは少なくとも 3 つあります。

  1. コマンドの標準エラー出力。今のところ、あなたはそれを飲み込んでいます2>&1systemその部分を削除し、コマンドが生成するエラーを観察します。
  2. の戻り値system。コマンドが実行されてsystemも終了コードが返される場合systemがありますが、0 が返された場合は、コマンドが成功したことがわかります。
  3. Perl のエラー変数$!. 問題があった場合、Perl は を設定$!しますが、これは役立つ場合とそうでない場合があります。

要約すると、次のことを試してください。

my $ec = system("command.pl >> /var/log/outlog");
if ($ec != 0) {
    warn "exit code was $ec, \$! is $!";
}

更新: コマンドの複数のインスタンスが出力に表示され続ける場合はps、プログラムが分岐してバックグラウンドで実行されているように聞こえます。それが実際にコマンドが行うべきことである場合、やりたくないことは、このコマンドを無限ループで実行することです。

于 2012-11-01T19:10:58.197 に答える
0

おそらく、デーモンから実行された場合、「システム」コマンドは、自分で実行しているときとは異なるシェルを使用しています。デーモンが使用するシェルが >& 構文を認識しない可能性があります。

于 2012-11-01T19:00:20.183 に答える
-3

の代わりに、機能する場合は関数system("...")を試してください。exec("...")

于 2012-11-01T19:01:35.690 に答える