shellの実行形式の違いでハマった話
背景
- mackerel でプロセス監視をしたかった
- この記事 を参考に yes コマンドを監視する shell を作った
- なんかすぐに発火して困ったので詳細調査した
現象
check-yes.sh を チェックプラグイン として送った瞬間にアラートが発火して止まらない
- mackerel の設定
[plugin.checks.yes]
command = "./usr/local/bin/check-yes.sh"
- 使ったスクリプト
$ cat check-yes.sh
#!/bin/bash
count=$(pgrep -c yes)
if test $count -eq 0; then
exit 0
else
exit 1
fi
対処
以下の設定にしたら期待通りの挙動になった
- 通常では何もアラート発火せず、yes コマンドを暴発したときだけアラートが上がる
[plugin.checks.yes]
command = ["bash", "/usr/local/bin/check-yes.sh"]
詳細調査
仮説: ./check-yes.sh
と bash check-yes.sh
で結果が違う?→違った
$ bash check-yes.sh
$ echo $?
0
$ ./check-yes.sh
$ echo $?
1
違い
bash check-yes.sh
- ”bash” が実行されていて、その引数に check-yes.sh っていう文字列が渡されている
./check-yes.sh
- “check-yes.sh”が実行されていて、インタプリタには/bin/bash を使いなさいとシバンで指定されている
要は実行結果が 1 だったのですぐにアラート発火していたということ
具体的に何が動いている?
検証
- pgrep の後に
ps aux | grep '[y]es'
ps aux | grep bash
を入れて表示させてみる
結果
$ ./check-yes2.sh
実行中のプロセス詳細(yes):
root 303185 0.0 0.0 6800 3108 pts/1 S+ 13:08 0:00 /bin/bash ./check-yes2.sh
実行中のプロセス詳細(bash):
velengel 300726 0.0 0.1 8236 4928 pts/0 Ss 12:49 0:00 -bash
root 300955 0.0 0.1 8104 4812 pts/1 S 12:49 0:00 -bash
root 303185 0.0 0.0 6800 3116 pts/1 S+ 13:08 0:00 /bin/bash ./check-yes2.sh
root 303191 0.0 0.0 6088 1924 pts/1 S+ 13:08 0:00 grep bash
$ bash check-yes2.sh
実行中のプロセス詳細(yes):
root 303176 0.0 0.0 6800 3104 pts/1 S+ 13:08 0:00 bash check-yes2.sh
実行中のプロセス詳細(bash):
velengel 300726 0.0 0.1 8236 4928 pts/0 Ss 12:49 0:00 -bash
root 300955 0.0 0.1 8104 4812 pts/1 S 12:49 0:00 -bash
root 303176 4.7 0.0 6800 3112 pts/1 S+ 13:08 0:00 bash check-yes2.sh
root 303182 0.0 0.0 6088 1912 pts/1 S+ 13:08 0:00 grep bash
学び
- ./の場合は実行中の自分自身をカウントしていた!!
- pgrep はほんとにプロセス名だけを見てくれるんだね
- 今回のポイントはプロセスの名前に yes が入っているかどうか
- bash 経由で実行するとプロセス名は bash になる
- ./で実行するとプロセス名は check-yes.sh が入る=yes が入ってくる
- mackerel のチェック監視の使い方を学んだ
- 今まではグラフで見たかったのでメトリック監視ばかりを使っていた
- チェックする対象が明確かつ簡単な実行結果で表せる場合はこっちの方がいいね
- こういう時(前提が足りてなかったり自分の中で説明がつかなかったりする時)は生成 AI に聞くのはよくない
- なんかよしなに説明をつけようとしてくる
- 久しぶりにググって誰かのメモ書きブログを読み漁るのをやった
参考
- https://penpen-dev.com/blog/shellscript-tigai/
- 実行形式の違いについて