プロセスをクリーンに終了する

プロセスをクリーンに終了する

Linux Ubuntu プラットフォームで、1 つのプロセスを自動的に開始および終了する必要があります。たとえば、午前 8 時の場合はプロセスが開始され、午後 7 時の場合はプロセスが終了されます。これは毎日行う必要があり、時間間隔を簡単に変更できれば問題ありません。

crontab で簡単なコードを使用しようとしています:

28 12 * * * /home/pi/Desktop/start.sh
50 11 * * * pkill led.py

時間を見ないでください。変更しようとしましたが、スクリプトstart.shが開始されますled.pyが、 を使用している場合は停止できませんpkill -9 -f led.py。プロセスは強制終了されますが、LED はオフになりません。プログラムを手動で開始し、Ctrl+で強制終了するとc、LED はオフになります。どこに問題があるのでしょうか。なぜプロセスを強制終了できず、同時に LED もオフにできないのでしょうか。

答え1

Ctrl+を入力するとc、通常はプロセスに「INT」信号が送信されます。signal(7):

  Signal     Value     Action   Comment
  ──────────────────────────────────────────────────────────────────────
  ...
  SIGINT        2       Term    Interrupt from keyboard

プロセスがこのシグナルのハンドラーをインストールして、終了前にクリーンアップを実行できるようにするのは一般的です。スクリプトの場合led.py、このハンドラーが LED をオフにしたようです。

デフォルトでは、pkillkillTERM」(15) シグナルを送信します。(「KILL」(9) の送信も試みました。) これらのシグナルにより、led.py終了関数を実行する機会が得られず、あまり優雅に終了しなくなります。

きれいに終了するにはled.py、「INT」(2)信号を送信する必要があります。

pkill -2 [process specifier]

指定した名前が検索対象ではなかったため、コマンドでプロセスを見つけられなかった可能性もありますpkillcrontabpkill(1):

-f, --full

パターン通常はプロセス名とのみ照合されます。-fが設定されている場合は、完全なコマンドラインが使用されます。

スクリプト はled.pyおそらく Python スクリプトなので、プロセス名は単にpython(またはpython3、または類似のもの) です。完全なコマンド ラインは のようになるpython led.pyので、-fオプションを使用してそれを一致させることができます。

pkill -2 -f led.py

答え2

私は何年も前からこの機能を使っています:

function killit () {
for process in "$@"; do
    kill -0 $process &>/dev/null
    if [[ $? == 0 ]] ; then
        sudo kill $process #(sends a TERM, wait 5 seconds)
        sleep 5
        RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
        if [[ $RUNNING ]] ; then
            echo "$0 WARNING: process $process still running, trying kill again"
            sudo kill $process #(yes, try again, wait 5 seconds)
            sleep 5
            RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
            if [[ $RUNNING ]] ; then
                echo "$0 WARNING: process $process still running, trying kill -INT"
                sudo kill -INT $process  #(wait for it)
                sleep 5
                RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
                if [[ $RUNNING ]] ; then
                    echo "$0 WARNING: process $process still running, trying kill -INT again"
                    sudo kill -INT $process  #(damn, still not dead?)
                    sleep 5
                    RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
                    if [[ $RUNNING ]] ; then
                        echo "$0 WARNING: process $process still running, trying kill -KILL"
                        sudo kill -KILL $process #(same thing as -9)
                        sleep 5
                        RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
                        if [[ $RUNNING ]] ; then
                            echo "$0 WARNING: process $process still running, trying kill -KILL again"
                            sudo kill -KILL $process #(something is wrong)
                            sleep 5
                            RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
                            if [[ $RUNNING ]] ; then
                                echo "$0 WARNING: Can't kill process $process"
                                logger "$0 WARNING: Can't kill process $process"
                            fi
                        fi
                    fi
                fi
            fi
        fi
    fi
done
}

関連情報