[Linux] 一定間隔でコマンドを実行する - watch

小ネタです。 特定のコマンドを一定間隔で自動的に実行したい場合は watch コマンドを使用します。

例えば以下のコマンドでwc -l foo.txtが10秒置きに実行されます。

$ watch -n 10 wc -l foo.txt

画面がwatchコマンド専用モードに切り替わります。終了したい場合はCtrl+cなどを入力します。

利用例

メモリ使用量

張り付きで監視する際にtopコマンドでは情報過多な場合に便利ですね。応用でdf -hとすればディスク使用量がチェックできます。

$ watch free -h

特定のプロセスを追いたい

こちらも張り付きで監視する際に、連続したpsコマンドの実行結果を覗く際に利用できます。

$ watch 'ps aux | grep http'

パイプやワイルドカードを使う

例えば以下のようにコマンドを実行すると、ワイルドカードはその場で展開され、パイプはwatchとは独立したコマンドであると解釈されるるため意図した通りに動いてくれません。

$ watch -n 10 tail /var/log/*.log
$ watch -n 10 grep XXX /var/log/foo.log | wc -l

このような場合は単純に引用符(コーテーション)で囲ってあげます。

$ watch -n 10 'tail /var/log/*.log'
$ watch -n 10 'grep XXX /var/log/foo.log | wc -l'

バッチ処理の進行状況を知る

長時間に渡るバッチ処理の進捗をずーと眺め続けるのは身体に良くないので、適当なログファイルに進捗を記録しておき別のプロセスでログファイルを覗き見るのが健康的です。

適当なログファイルにリダイレクト等で記録しておき、

$ nohup ./longtime.sh >> log.txt &

別のTerminalなどからwatchコマンドで適当に集計するなどして進捗を確認してやります。

$ watch wc -l log.txt

※コマンドの最後に'&'を付けるとバックグラウンドで実行されます。nohupを付けるとTerminalを閉じてもバックグラウンドの実行が終了されなくなります。

その他

macOSで利用する

大抵の場合Linuxには最初から入っていますが、macOSの場合はHomeBrewなどでインストールします。

$ brew install watch

オプション一覧

-d, --differences
前回の実行結果と異なる場所をハイライト表示
-n, --interval 秒数
コマンドを実行する間隔を秒数で指定する。最少は0.1秒。(未指定時は2秒間隔)
-p, --precise
より厳密な秒数でコマンドを実行
-t, --no-title
ヘッダーを表示しない
-b, --beep
コマンドがエラー終了した場合にビープ音を鳴らす(戻り値がゼロでなかった場合)
-e, --errexit
コマンドがエラー終了した場合にwatchコマンドも終了する(戻り値がゼロでなかった場合)
-g, --chgexit
コマンドの実行結果が前回と変わった場合にwatchコマンドも終了する
-c, --color
ANSI形式で色やスタイルの指定を行う
-x, --exec
コマンドを execで実行する(未指定時はsh -c

参考ページ