kshスクリプトのバックグラウンドプロセスが起動後に消えます。

kshスクリプトのバックグラウンドプロセスが起動後に消えます。

バックグラウンドで4つのプロセスを並列に開始し、その状態をポーリングする必要があるKSHスクリプトに問題があります。

簡単に言えば、この4つのプロセスを順番に実行するのは時間がかかりますが、並列に実行すると時間を大幅に節約できると思います。理論的には、実装するのは難しくないと思い、以下のコードを書いています。各プロセスはバックグラウンドで開始され、対応するpidは変数に保存されます。

すべてのプロセスが開始したら、次のように各PIDを確認したいと思います。ps -p $PIDプロセスがまだ存在していることを確認してください。そうでない場合は、ループを終了して次のループに進みます。これは順番に行われます。

プロセスを最大限に最適化したいという事実は取り除き、この時点でプロセスが消える非常に継続的な問題に直面することになります。バックグラウンドでプロセスを開始し、そのpidが変数に割り当てられますが(対応する変数がいっぱいになることを確認できます)、同じPIDを使用して直接プロセスを照会しても何も返されません。プロセスが消えます。

これは4つのプロセスすべてで発生します。バックグラウンドで実行しなくても(アンパサンドを削除すると)、コマンドは正常に機能します。したがって、問題は、必要なコマンドをバックグラウンドプロセスとして実行することに関連しているようです。

たとえば、私が実行した場合睡眠 180後で同様の方法でPIDを保存し、同じ方法でクエリを実行すると、目的の結果が得られます。

したがって、フォアグラウンドでプロセスを実行し、バックグラウンドで別のプロセスを実行できます。私にとっては、不明な何らかの理由でこれらの特定のプロセスをバックグラウンドで実行することはできません。実行するコマンドのすべての出力をログファイルに書き込むと、空のログファイルが返されます。使用セット-x奇妙なことを示していませんでした。

以下の公開スクリプトは多くのチェックを実行し、多くの機能を含む3番目のスクリプトを呼び出す別のスクリプトを呼び出します。これまで、スクリプトでそのような問題が発生する可能性があることを示すものは見つかりませんでした。

したがって、基本的に状況は次のようになります。
- このスクリプトの前景から必要なコマンドを実行すると正常に動作します。
- このスクリプト内でバックグラウンドで別のコマンド(たとえば、スリープ)を実行するとうまく機能します。
- バックグラウンドのシェルから直接必要なコマンドを実行すると正常に動作します。
- このスクリプト内でバックグラウンドで必要なコマンドを実行すると、何の効果もなく、識別可能なエラーは発生しません。

私はこの時点でこの問題について完全に苦労しました。誰かが私にこれがなぜ機能しないのかについての漠然とした考えを与えることができますか?

checkStatus(){
  LV_PID=${1}
  LV_COUNTER=0

  while (( ${LV_COUNTER} == 0 ))
  do
    ps -p ${LV_PID}
    if (( $? == 0 )); then
      ##continue loop
    elif (( $? == 1 )); then
      LV_COUNTER=1
    fi
  done
}

#################################################
#  Function: intendedFunction                   #
#################################################
intendedFunction(){
  nohup examplecommand.ksh -t exampletarget1 2> $HOME/log1.txt 1> /dev/null &
  export pid1=$!
  nohup examplecommand.ksh -t exampletarget2 2> $HOME/log2.txt 1> /dev/null &
  export pid2=$!
  nohup examplecommand.ksh -t exampletarget3 2> $HOME/log3.txt 1> /dev/null &
  export pid3=$!
  nohup examplecommand.ksh -t exampletarget4 2> $HOME/log4.txt 1> /dev/null &
  export pid4=$!

  echo "pid1 is $pid1"
  echo "pid2 is $pid2"
  echo "pid3 is $pid3"
  echo "pid4 is $pid4"

  checkStatus $pid1
  if (( `wc -l < log1.txt` == 0 ))
  then
    #success
  else
    #error
  fi
  checkStatus $pid2
  if (( `wc -l < log2.txt` == 0 ))
  then
    #success
  else
    #error
  fi
  checkStatus $pid3
  if (( `wc -l < log3.txt` == 0 ))
  then
    #success
  else
    #error
  fi
  checkStatus $pid4
  if (( `wc -l < log4.txt` == 0 ))
    #success
  else
    #error
  fi

ベストアンサー1

コマンド名にタイプミスが含まれているか、パスにexamplecommand.kshが見つからないなどの基本的な問題があるようです。

pid変数は実際に行われたかどうかにかかわらずnohupによって埋められ、nohupがコマンドの実行に失敗するとすぐに終了します。さらに、nohupは完全に失敗しても不快なエラーメッセージでユーザーを悩ませません。

[ksh]$ nohup nonexistent.ksh &
[1] 32938
appending output to nohup.out
[ksh]$ echo $!
32938
[1] +  Done(127)               nohup nonexistent.ksh &

PS。 xargsを見たいと思うかもしれません。のように

[ksh]$ seq 1 4 | xargs -n 1 -P 4 -I PART echo "part PART finished" 
part 2 finished
part 1 finished
part 3 finished
part 4 finished

おすすめ記事