watchコマンドの代わりになるシェルスクリプト

Linuxにはwatchコマンドというのがある。一定時間ごとに引数のコマンドを実行して、出力を監視することができるコマンドで、例えば、

% watch  cat /proc/meminfo

などとすれば、メモリの使用状況を監視することができる。

Mac OS X環境でも同じことをするコマンドが欲しかったので、シェルスクリプトで作ってみた。
-nオプションで、周期を指定する。0.5などと、小数でもOK。

#!/bin/zsh
wait=2
clear="\033[H\033[J"

while getopts n: o; do
    case $o in
        n)   wait=$OPTARG;;
        [?]) print >&2 "Usage: $0 [-n wait] command ..." ; exit 1;;
    esac
done
shift $OPTIND-1

while ( true ); do
    let prompt_x=$COLUMNS-19
    date="\033[0;${prompt_x}H\033[1;32m "`date +'%Y/%m/%d %H:%M:%S'`"\033[0m"
    $* |& awk "BEGIN{print \"$clear\" substr(\"$*\",0,$prompt_x) \"$date\"} {print}" | cat
    sleep $wait
done

おまけでヘッダに実行中のコマンドと現在時刻を表示している。時刻があるとコマンドの出力が変わっていなくても一応動いていることが確認できて良いので付けてみた。

やたらと変数に溜め込んだり、awk 〜 | cat などと変なことをしているのは、いったんバッファリングしてから出力することで、出力がちらつくのを防ぐためだ。こうしないと、0.1などと高速な指定をした時に、clearでしょっちゅう文字が消えるのが見えて、結果が読めない。