Last-modified:2016/11/09 11:39:28.
計算機の使い方を教えるのを効率化したい。 [2016-11-09]
『UNIX今日の技』は、「UNIX 初心者が中級者にレベルアップするための足掛かり」となる事を目的としています。 ですので、「ls って何?」というようなレベルの人はまず本などで(基本的なコマンド程度で良いので)勉強してからにした方が良いと思います。
あと、当研究室特有の事情や研究でよくなされる作業(VASP を使うなど)をそのまま例に挙げることがよくあります。
(今まさに表示されている)このページに書かれているのは最新の記事であり、書いてから暫く時間の経った物は適当なタイミングで Archives に放り込んでいます。
シェルスクリプト を追加しました。[2016-11-09]
世の中にはビープ音を嫌う人もいるらしいですが、 上手に使うと嬉しい場面が結構あります。 具体的には、計算機に何か時間のかかる仕事をさせているときに、 その仕事の終了したときに音で知らせてくれるようにできます。 たとえば以下のような仕事は日常でもよくあります。
勿論ビープ音じゃなくて音楽ファイルを再生してライン出力から流す方法もありますが、 これにはスピーカーが必要ですし、 ヘッドホン環境ではヘッドホンをつけていなければならないという条件があります。 私の場合、いつでもビープでほとんど問題ありません。
まず簡単には beep コマンドをインストールしてみましょう。 apt-get などでパッケージインストールできる筈です。 時間のかかるコマンドのテストには sleep コマンドを使うのが定石です。
sleep 1; beep
これで1秒後にビープが鳴ってくれれば成功です。 sleep のところを vasp などと置き換えれば、 仕事が終わったときにビープで通知してくれるようになるわけです。
別室に置いてある計算機に ssh でログインし、そこで beep してみましょう。 自室の端末ではビープが鳴りません。 beep コマンドは、実行されたコンピュータのマザーボード上で再生されるので、 別室で計算機がひっそりとビープを鳴らしている事になります。 欲しい結果は自分が今操作している端末でビープが鳴ってくれることであり、 リモートホストでビープを鳴らすことではありません。
その目的にはどうすれば良いでしょうか。 ASCII 文字にベル文字が定義されています。 主要なターミナルエミュレータは ベル文字の出力に対してビープ音を発音します。 これを試してみましょう。
echo "\a"
ちゃんと鳴ればおめでとう!
でも鳴らない環境も結構あります。 鳴らない場合は、OS か ウィンドウマネージャで止められている可能性があります。 OS に関しては、たとえば Ubuntu の場合、 “/etc/modprobe.d/blacklist.conf” で pcspkr と snd_pcsp がブラックリストに入っている(無効化されている) のがデフォルトです。 これらの行をコメントアウトしましょう。 岸田は以下のようなシェルスクリプトを使った上で再起動しています。
#! /bin/sh
BLACKLIST="/etc/modprobe.d/blacklist.conf"
BLACKLIST_BAK="/etc/modprobe.d/blacklist.conf.00"
cp $BLACKLIST $BLACKLIST_BAK
cat $BLACKLIST_BAK | sed 's/blacklist pcspkr/#blacklist pcspkr/' | sed 's/blacklist snd_pcsp/#blacklist snd_pcsp/' > $BLACKLIST
rm $BLACKLIST_BAK
ウィンドウマネージャ では、Gnome なんかは止めるのがデフォルトっぽいです。 通す方法もあるのかもしれませんが、私は知りません。 これが、私が Gnome を好きになれない理由の一つです。 岸田は icewm を使っています。 icewm でビープが鳴れば、Gnome が原因と特定できます。
ターミナルエミュレータにも依存するかもしれません。 岸田は rxvt を使っています。
あと、鳴る筈なのに鳴らない……と悩んだ原因が、 マザーボードの SPEAKER 端子にビープ用スピーカーを繋いでいなかった、 ということもよくあります。
何らかの障害が生じて目的ホストにネットワークが繋がらないなど、 ネットワーク管理者ならしばしば直面する事でしょう。 ネットワークの導通やホストの稼動をチェックするのには、 ping が最も基本的なツールです。 リモートホスト Kr00 へのネットワーク導通を確認するには、
ping Kr00
などとしておいて、その間のハブやケーブルをチェックし、 その都度導通を確認する、ということはよく行われていることと思います。 さて、この ping でビープを鳴らしましょう。 ping の返り値を使ってベル文字を echo する方法もありますが、 もっと簡単にできます。 ping には -a オプションがあります。 man ping してみましょう。
-a Audible ping.
はい。
ping -a Kr00
導通すれば 1秒ごとにピッピッピッと音がする筈です。 これでわざわざ画面を見なくても、 障害のある箇所を改善して導通があれば音で確認できます。 1000ms オーダーの遅延が生じる場合も直感的に分かります。
システム管理者は 計算機の再起動をすることがしばしばあります。 起動するまでじっと画面を睨んでいることはあまりなく、 その間に他の作業をしたりします。 そこで、「起動したら音を鳴らして通知してほしい」という要求があります。
ネットワークの導通チェックは、 計算機の再起動通知にも使えます。 Kr00 を再起動したら、ローカルホストで以下のようになれば ネットワークインターフェイスが立ち上がったところでピッピッピッと鳴ります。
ping -a Kr00
本節は、パスフレーズなしでログインできることが前提です。
ping が開通してから ssh ログインできるまでは、 10秒程度かそれ以上かかることがあります。 計算機の起動通知はそこで操作したいからなので、ping 導通からログイン可能までの この時間が鬱陶しい。 さあ、ssh ログインでビープ音を鳴らしてみましょう。 たとえば、以下のようにしてみましょう。
ssh Kr00 echo "'\a'"
リモートホストに ssh ログインし、 そのホストでベル文字を出力、 するとローカルホストのターミナルエミュレータがベル文字の出力としてローカルホスト にビープ音の発音を要請する、ということになり、望む結果が得られます。 あとはこれを繰り返すだけです。 インスタントには以下のような感じですかね。
while true; do ; (ssh Kr00 echo "'\a'"; sleep 1;) ; done
ちょっと面倒だし、ループ的にちょっと打ち難い感じがあります。
数秒おきに 同じ処理を繰り返すのには watch コマンドが便利です。
watch ssh Kr00 echo "'\a'"
おっと、「a」としか出てきませんでした。 watch コマンドのベル文字解釈か、シェルのクォート解釈がひっかかっているみたいですね。 実は、watch コマンド自体がビープ音を鳴らす仕組みを持っています。 man watch してみましょう。
-b, --beep
Beep if command has a non-zero exit.
-b オプションで、返り値が非零を返したときにビープを鳴らしてくれるそうです。 なんとなく上手く使えそうですが、ちょっと待ってください。 ping は応答があったときに零を返し、応答がなかったときに非零を返します。 このまま使うと、ピッピッピッと音が鳴り続けて音が止んだときにログイン可能となります。 これでも使えないことはないですが、逆が好ましいです。 そういう時は「!」で返り値を反転しましょう。
watch -b ! ssh Kr00 echo
これで、Kr00 がssh ログインできるようになるまでは沈黙し、 なったらピッピッピッと鳴ってくれるようになります。 echo コマンドから “‘’” がなくなっていますが、 これは bell 文字の出力を echo で行わなくても良くなったからです。 さらに言えば echo を使う必要もなく、 exit や hostname コマンドなど入力の必要のないコマンドなら何でも良いです。
このチェックをよく使うのなら、watchssh とかいう名前で使えるように、 ~/.zshrc あたりに以下のように仕込んでおいても良いでしょう。
function watchssh() {command watch -b ! ssh $* echo}$
VASP 計算のような負荷のかかる仕事が終了したことをビープで通知して欲しいですね。
watch -b 'ps auxw | grep -v grep | grep vasp'
というようにすると、vasp という文字列を含むプロセスが存在しなくなったときに ビープを鳴らします。 少し使ってみると、今度は任意のプロセスで使えるようにしたい……と思うでしょう。 私もそうです。 ということでコマンドライン引数でプロセスに含まれる文字列を取れるように拡張します。
function watchpstrue() {command watch -b ! "ps auxw | grep -v grep | grep $*" }
function watchpsfalse() {command watch -b "ps auxw | grep -v grep | grep $*" }
岸田は ~/.zshrc に仕込んであります。 ps で表示される全プロセスの中に引数で渡した文字列が含まれるプロセスが存在すれば、 前者は音を鳴らします。 後者は逆です。