起動時間が一定以上のプロセスをKillするスクリプト

2024-06-13

長時間起動したままのプロセスをKillする

Cronで実行するスクリプトで実行時間が短いはずなのに長時間起動したままで終了していないプロセスがあり、プロセスが残っていた状態でメモリが使用率が増えるケースがありました。

1週間以上とか起動したままのプロセスを手動でKillしてましたが、いつもKillコマンドなので終了していたのを、ある一定上経過しているとKillしてくれるスクリプトを紹介します

長時間起動しているプロセス・スクリプトをKillするシェルスクリプト

長時間起動しているスクリプト・プロセスをKillするシェルスクリプトですが、Killする条件ですが下記の条件とします

  • 自分自身のプロセスはKillしない
  • 起動時間は一定以上のみKillする(下記のスクリプトでは10分以上の場合)

起動時間の取得方法ですがpsコマンドでもプロセスの起動時間を取得できますが、psコマンドのTIMEはCPUの起動時間となってるのでCPUを使っていない状態で残っていると00:00のままとなり正しく取得できないので、プロセス自身の起動時間を「ps -o lstart –noheader -p (プロセスID)」で起動時間を取得して、現在の時刻と先ほど取得した時刻から経過時間を取得します。

サンプルのシェルスクリプトは以下のような感じです。下記のスクリプトでは「test.sh」というスクリプトが10分以上経過しているとKillしています。

ProcessName=test.sh の箇所を違うプロセス名に変更すると違うプロセスでも対応できます

#/bin/bash

ProcessName=test.sh
PID=$$
for i in `ps -ef | grep "$ProcessName" | grep -v $PID | grep -v grep | awk '{print $2}'`
do
  TIME=`ps -o lstart --noheader -p $i`
  if [ -n "$TIME" ]; then
    StartupTime=`date +%s -d "$TIME"`
    CurrentTime=`date +%s`
    ElapsedTime=`expr $CurrentTime - $StartupTime`
  else
    ElapsedTime=1
  fi

  if [ $ElapsedTime -gt 600 ] ; then
    kill $i
  fi
done

簡単にですが、シェルスクリプトを説明します

ProcessName=test.sh
「ProcessName」はKillする対象のプロセス名称となります。

PID=$$
「PID=$$」は、実行している自分自身のプロセスIDです

for i in `ps -ef | grep “$ProcessName" | grep -v $PID | grep -v grep | awk '{print $2}’`
psコマンドの結果を、Killするプロセス名称で絞り込み、その中から、自分自身のプロセスID($PID)とgrepコマンド自身を除いたプロセスIDを取得しています。その結果をforで順番通りに処理していきます

TIME=`ps -o lstart –noheader -p $i`
プロセスIDの起動時間(TIME)を取得しています

StartupTime=`date +%s -d “$TIME"`
起動時刻をUNIX時刻に変換(StartupTime)しています

CurrentTime=`date +%s`
現在の時刻をUNIX時刻に変換(CurrentTime)しています

ElapsedTime=`expr $CurrentTime – $StartupTime`
UNIX時刻で引き算をして、経過時間(ElapsedTime)を取得しています

if [ -n “$TIME" ]; then
<者略>
else
ElapsedTime=1
この処理ですが、取得したプロセスIDのプロセス終了したりするケースだと$TIMEが取得できませんのでその場合は経過時刻を1秒とするようにしています

if [ $ElapsedTime -gt 600 ] ; then
kill $i
fi
600秒(10分)以上の場合は、該当のプロセスIDをKillしています。

処理がかかるプログラムだと10分間起動したままも珍しくないので、起動したままで正常終了していないプロセスのみ終了するには24時間(86400)に設定する方がいいと思います

こちらの長時間起動しているプロセス・シェルスクリプトを削除するスクリプトですが、過去の記事でUNIX時刻を利用して、時刻の引き算する方法を紹介した記事の応用ですので、そちらの記事も参考にして下さい

Linuxで2つの時刻の引き算して時刻を計算する