エンジニアリングマネージャー見習いの個人開発備忘録

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.shbash 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 に聞くのはよくない
    • なんかよしなに説明をつけようとしてくる
    • 久しぶりにググって誰かのメモ書きブログを読み漁るのをやった

参考