CLIマジック:ANSIエスケープシーケンスを使って端末に時計を表示する

 Linux端末を使っているとき、時刻を知るためだけにdateコマンドを実行していることが私にはよくある。これをもっと簡単にするため、端末画面の右上隅に常に時計が表示されるようにするスクリプトを作成してみた。

 このスクリプトでは、ANSIエスケープシーケンス命令を使って現在のカーソル位置を保存する。次に、tputコマンドを使って、カーソルを0行(画面の一番上)の最後のカラムから19キャラクタ目(19というのは「HH:MM:SS YYYY-MM-DD」の長さである)に移動し、フォーマット指定したdateコマンドの出力を反転した緑色で表示する。そして、保存された元の位置を復元するため、別のANSIシーケンスを使ってカーソルを元の位置に戻す。

 X Window Systemの端末を使っている場合、ウィンドウのサイズを変更すると時計の位置が調節される。これは、最後のカラムから19キャラクタ目に時計が表示されるようになっているためだ。ANSIエスケープシーケンスはすべての端末エミュレータで動作するわけではないが、xtermなら問題ない。スクリプトは次のとおり。

#!/bin/bash
# clock.sh

# the script is executed inside a while without conditions
while :
do
 # time and date are formatted to show HH:MM:SS YYYY-MM-DD
 cmd=`date +"%H:%M:%S %F"`

 # cursor's current position is saved through an escape sequence
 echo -n -e "\033[s"

 # Uncomment the next two lines to clean up the whole first line, although it causes a lot of blinking
 #tput cup 0 0    # positions on row 0 col 0 (left top corner)
 #tput el         # cleans from position to end of line

 # to place the clock on the appropriate column, subtract the length of 'HH:MM:SS YYYY-MM-DD', which is 19,
 # from the total number of columns
 C=$((`tput cols` - 19))
 tput cup 0 $C    # positions cursor at row 0 col $C

 # clock will be shown green inverted
 # setaf 2 = green, smso = inverted
 COLOR=`tput setaf 2; tput smso`

 # back to normal screen colors
 NORMAL=`tput sgr0`

 # print the time-date output on the above position
 echo -n $COLOR$cmd$NORMAL

 # restore the cursor to whatever was its previous position
 echo -n -e "\033[u"

 # script is executed every second
 sleep 1
done

 このスクリプトをclock.shとして保存し、chmodで755に設定し、「./clock.sh &」で実行する。これで時間と日付が画面の右上隅に表示されるはずだ。

 clock.shを実行すると、ジョブ番号とclock.shのプロセスのプロセス識別子(PID)が端末から返される。実行中のスクリプトを終了させるには、killコマンドにジョブ番号を指定する。

 このスクリプトを使うと、時計以外にも役立つ情報を表示することができる。たとえば、uptimeコマンドを使ってCPUの平均負荷を監視したいとする。

uptime
09:19:56 up 1 day,  1:54,  4 users,  load average: 0.29, 0.39, 0.42

 最後の3つの値が、それぞれ過去1分間、5分間、15分間の平均負荷だ。これらの値を取り出すにはgawkコマンドを使うとよい。

uptime | gawk '{print $(NF - 2), $(NF - 1), $NF}'
0.72, 0.54, 0.47

 NFは出力されたフィールドの総数で、$NFは最後のフィールドの値である。clock.shで次の行を変更する。

cmd=`date +"%H:%M:%S %F"`

 これを次のようにする。

cmd=`uptime | gawk '{print $(NF - 2), $(NF - 1), $NF}'`

 次のようにして時間と日付を残してもよい。

cmd=`date +"%H:%M:%S %F" ; uptime | gawk '{print $(NF - 2), $(NF - 1), $NF}'`

 文字列の長さが19キャラクタ以内になっているので、wcコマンドで表示する位置を決めるようにするとよいだろう。変更するのは次の行だ。

C=$((`tput cols` - 19))

 これを次のようにする。

C=$((`tput cols` - (`echo $cmd | wc -c` - 1) ))

 出力の長さは「wc -c」(wc-cオプションを指定すると、パイプで送られた文字列のキャラクタ数がカウントされる)で算出する。-1は、$cmdの出力の最後の\rを除外するためだ。

 その他にも、使用量が増えていくパーティションの全体のサイズや利用可能な容量をdfコマンドを使って表示したり、オンラインのユーザーをuptimeまたはwコマンドで表示したり、psでプロセス数を表示したりすることができるだろう。Samba、Apacheなどさまざまなサーバーには状態通知コマンドがあるので、この方法で情報を取り出して表示できる。イマジネーションを働かせて変更を加え、オリジナルバージョンのclock.shを作ってみて欲しい。

Sergio Gonzalez Duranは、Linuxの管理、システム開発、ネットワークセキュリティのカウンセリングに従事している。また、Linux講座の講師を務め、スペイン語向けのLinuxやオープンソースWebサイトのlinuxtotal.com.mxを公開している。

Linux.com 原文