2月 142014
cron
だ。ただ、cron
ならcrontab -l
をしたり、直接/var/spool/cron/crontabs/*
を調べれば、どんなコマンドが実行されるかすぐに調べがつく。しかし、あるイベントが発生したことをトリガーにしてコマンドが実行された場合、なぜそのコマンドが突然呼ばれたのかということに困惑することがある。
例えば、ifup
コマンドが実行された場合、/etc/network/if-pre-up.d
と/etc/network/if-up.d
配下にあるコマンドが、ifup
の実行中に呼び出されるようになっている。あるコマンドが実行されていることはログなどからわかっているが、どのような経緯で実行されるに至ったかがわからない、という場合には、そのコマンドの親プロセスを辿っていけば調べることができる。
実行されているコマンドがバイナリだと手も足も出ないかもしれないが、シェルスクリプトであれば、以下のようなスクリプトを使って呼び出し元の親プロセスたちを辿ることができる。
trace_parents() { local pid=$$ cmd while true; do cmd="$(cat /proc/$pid/cmdline | tr '\0' ' ')" echo -e "pid=$pid, cmd=$cmd" [ $pid -eq 1 ] && break pid=$(awk '/^PPid:/{print $2}' /proc/$pid/status) done } trace_parents > /tmp/parents.$(basename $0).log
PIDが1、すなわちinit
になるまで/proc/pid/status
の中から親プロセスのPIDを辿っていくというものだ。/proc/pid/cmdline
をcat
でダンプさせると、コマンドライン引数の間にスペースがないように見えるが、区切り文字はnull文字(\0
)になっているので、tr
でスペースに置換すれば見やすくなる。