8

X秒ごとにアプリケーションを実行する必要があるため、cronがこのように秒で機能しない限り、X秒がスリープする無限ループを使用してbashスクリプトを作成しました。

実行中のスクリプトを手動で停止する必要がある場合は、正しい方法で停止したいと思います。アプリケーションを完全に機能させ、次回はループに入らないようにします。

これをどのように達成できるか、何か考えがありますか?引数を渡すことを考えましたが、実行中のスクリプトに引数を渡す方法が見つかりませんでした。

4

4 に答える 4

26

シグナルをトラップすることができます、例えばSIGUSR1:

echo "My pid is: $$"
finish=0
trap 'finish=1' SIGUSR1

while (( finish != 1 ))
do
    stuff
    sleep 42
done

次に、次の反復でループを終了する場合:

kill -SIGUSR1 pid

pidスクリプトのプロセスIDはどこにありますか。スリープ中に信号が発生すると、スリープはスリープ解除されます(信号が発生するまでスリープはスリープします)。

于 2012-06-26T08:32:20.393 に答える
2

いくつかの引数をファイルで渡すことができます。各反復で、このファイルを読み取り、実行条件が変更されたかどうかを確認できます。

于 2012-06-26T08:16:55.253 に答える
1

とにかくクリーンアップを行う必要がある場合は、次の構造が適切な場合があります。cdarkeの答えに示されているようにkillを使用します。

#===============================================================
#  FUNCTION DEFINITIONS
#===============================================================
# . . .

#===  FUNCTION  ================================================
#          NAME:  cleanup
#   DESCRIPTION:  
#===============================================================
cleanup ()
{
  # wait for active children, remove empty logfile, ..., exit
  exit 0
} # ----------  end of function cleanup  ----------

#===============================================================
#   TRAPS
#===============================================================
trap  cleanup SIGUSR1

#===============================================================
#   MAIN SCRIPT
#===============================================================
echo -e "Script '$0' / PID ${$}"

while : ; do                                # infinite loop
  # . . .
  sleep 10
done
# . . .

#===============================================================
#   STATISTICS / CLEANUP
#===============================================================
cleanup
于 2012-06-26T12:29:42.230 に答える
1

以前に投稿されたトラップソリューションは、大きなループには適していますが、1つまたはいくつかのコマンドをループするだけの一般的なケースでは面倒です。この場合、次の解決策をお勧めします。

while whatever; do
    command || break
done

これは、コマンドにゼロ以外の終了コードがある場合にループを終了します。これは、コマンドが中断された場合に発生します。したがって、commandハンドルがない限りSIGINT、ctrl-Cを押すと、現在のコマンドが停止し、ループが終了します。

編集:質問を詳しく読んだ後、現在のコマンドの実行を継続する必要があることがわかりました。その場合、この解決策は適用されません。

于 2013-02-06T10:45:29.693 に答える