Why not login to Qiita and try out its useful features?

We'll deliver articles that match you.

You can read useful information later.

0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Bashスクリプトでプロセス監視 -> Dockerコンテナでコマンドを自動実行を実現する方法を考えてみた

Last updated at Posted at 2025-01-24

背景

この記事では、指定したプロセスの監視を行い、すべてのプロセスが終了した後に特定のコマンドをDockerコンテナ内でバックグラウンド実行するBashスクリプトについて紹介します。

このスクリプトがなぜ必要になったかというと、
OOMを避けるために今動いているプロセスが止まったら、別プロセスを実行したい!
でもずっと、プロセスが終わるのを休日も物理的に監視し続けるのは非現実的!
みたいな感じで、スケジューラーのようなものを考えてみたのがキッカケです😎
備忘録として、スクリプト例を以下に記します。

スクリプト例:

ファイル名 : monitor_and_run.sh

#!/bin/bash


# 監視するプロセスのPID
PID1=31515 #任意のPID
PID2=35036 #任意のPID

# Dockerコンテナ名
CONTAINER_NAME="my_container"

# 監視が終わったら実行するコマンド
COMMAND_TO_RUN="pyenv activate myenv && cd /workspace/project/src && ./hello.sh"

# フラグ管理
PID1_COMPLETED=false
PID2_COMPLETED=false

# ログ用のタイムスタンプ関数
timestamp() {
    date "+%Y-%m-%d %H:%M:%S"
}

# 監視ループ
while true; do
    # PID1の存在確認
    if ! $PID1_COMPLETED; then
        if ps -p "$PID1" > /dev/null 2>&1; then
            echo "[$(timestamp)] [INFO] Process with PID $PID1 is still running."
        else
            echo "[$(timestamp)] [INFO] Process with PID $PID1 has completed."
            PID1_COMPLETED=true
        fi
    fi

    # PID2の存在確認
    if ! $PID2_COMPLETED; then
        if ps -p "$PID2" > /dev/null 2>&1; then
            echo "[$(timestamp)] [INFO] Process with PID $PID2 is still running."
        else
            echo "[$(timestamp)] [INFO] Process with PID $PID2 has completed."
            PID2_COMPLETED=true
        fi
    fi

    # 両方のPIDが終了したらコマンドを実行してループを抜ける
    if $PID1_COMPLETED && $PID2_COMPLETED; then
        echo "[$(timestamp)] [INFO] Both processes have completed."
        echo "[$(timestamp)] [INFO] Executing command in container '$CONTAINER_NAME'."

        # Dockerコンテナ内でコマンドを実行(バックグラウンドで実施)
        if nohup docker container exec "$CONTAINER_NAME" bash -c -i "$COMMAND_TO_RUN"; then
            echo "[$(timestamp)] [INFO] Command executed successfully in container."
        else
            echo "[$(timestamp)] [ERROR] Failed to execute command in container."
        fi
        break
    fi

    # 1分待機
    sleep 60
done

exit 0

実行コマンド

#実行したディレクトリ配下に指定のログファイルを出力する
nohup ./monitor_and_run.sh > test.log 2>&1 &

つまづいたポイント

  • 今回最終的に実行するhello.shは中でpythonコマンドを実行するので、pyenvの仮想環境をアクティベートさせて実行する必要がありました。
  • そこでつまづいた点として、bashの-iオプションがないとインタラクティブモードにならずシェルの設定ファイル(~/.bashrcなど)が読み込まれないので、環境変数のパスが通らずpyenv環境でpythonが実行されませんでした...。

注意点

  • 任意のプロセスID (PID) は、スクリプト実行前に正しいPIDを取得してください。
  • スクリプト内のコマンドは、適宜環境に合わせて編集してください。
  • 実行前にchmodコマンドなどで実行権限を付与してあげて下さい。

まとめ

私自身の備忘として残しましたが、どなたかの参考になれば幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?