他のプログラムの標準出力にしたがって動くシェルスクリプト
要約
他のプログラムにパイプで繋ぐことで,そのプログラムの標準出力を受け取り,出力にしたがって動くシェルスクリプトの作成方法.
要件
今回はパフォーマンス測定のためのツールとして作成した.
ここでは,プログラム中のある点での /proc/meminfo
を知りたいとしよう.
このとき,プログラムを改変して,fork等呼び出せばできるがあまりにめんどくさい.
よってここで決められた文字列(たとえば"meminfo_record")を出力することで,これを記録するような別のスクリプトを動作させることを考える.
このとき,記録用のシェルスクリプト自体に時間を取られないことが肝要である.
まとめると以下.
- パイプで起動(e.g.
$ target_proc | measure.sh
) - 入力は基本teeみたいに受け流し.ただし特定入力(e.g.
"meminfo_record"
)については別コマンド実行. - ポーリングではなく,イベント駆動
答え
#!/bin/bash while read line do echo "$line" if [ "$line" = "meminfo_record" ]; then break fi done cat /proc/meminfo > meminfo.log
ハマった落とし穴
whileの書き方によって無限ポーリングしてハマる.
while : do read line echo "$line" if [ "$line" = "meminfo_record" ]; then break fi done
バックグラウンドで測定開始,後に終了させる
今回はmeminfo一発で終わりだが,ここでパフォーマンス測定プロセスを開始し,後にそれを終了させたいような場合を考える. このとき,
- バックグラウンド実行
- PID取得
- シグナル送信
の3つのテクニックが鍵となる.
バックグラウンド実行
some_command &
PID取得
some_command & pid=$!
シグナル送信
ここではC-cみたいなの.
kill -INT $pid