綾小路龍之介の素人思考

[処理制御] 10秒間処理を停止する

もっとも問題なのはこの手の処理がWindowsに標準でついていないことじゃないかな。昔はプロセスの起動と終了を監視するプログラムを作ったもんだ。まぁそんなに厳密にならなくていい場合はsleep文で済ませてしまえばいい。perlの一行スクリプトでそんなことができるなんていい時代になったもんだ。

> perl -e "sleep(10)"

単独ではほとんど意味ない。でも、Windowsのバッチファイル中で使うと少しいいことあるかもしれない。なぜなら、バッチファイルの処理分岐は別ウィンドウで起動されるプログラムの終了コードを判別しないからだ。つまり、バッチプログラムはMS-DOSプロンプトに処理結果を返すプログラムについては、終了後に先のプログラムの結果を利用することができるが、そうでない場合はただのアプリケーションランチャとしてしか使えない。したがってアプリケーションAが終了するまでに十分な時間を上のように書くことでsleepさせて、その後に別のアプリケーションBを起動することもできる。

思いついた使い方としてはラーメンタイマーなんだな。下のように書いてみた。

> perl -le "for(1..6){sleep(3); print scalar localtime;}print qq/\a/x10;"
Sun Mar 26 01:57:20 2006
Sun Mar 26 01:57:22 2006
Sun Mar 26 01:57:26 2006
Sun Mar 26 01:57:29 2006
Sun Mar 26 01:57:31 2006
Sun Mar 26 01:57:35 2006

100分の1秒までこだわりたいなら次のようにもできる。カップラーメン作るのに100分の1秒までこだわらなくても上の例よりも短くかけてほとんど同じ効果をもたらすのでこちらの方がいいかもしれない。こちらはプログラム的にはあまりよろしくないが、3分待つにはどうでもいいことだ。よろしくないのはprint文に続くtimesをスカラーとして評価する時に無理やり0を足し算することでこれをなしている点。本来ならばscalar timesとするべきかも。でもこの方が短いので文字数制限のあるコマンドプロンプトではそのほうがいいかも。

> perl -le "for(1..6){sleep(3); print 0+times;}print qq/\a/x10;"
3.08
6.1
9.07
12.09
15.11
18.07

あわせ技でこんなのもありかな。timesのスカラー評価に同じ手法を使った。

> perl -le "for(1..6){sleep(3); print join' ',map{scalar localtime $_}(time,times+15*60*60);}print qq/\a/x10;"
Sun Mar 26 02:48:10 2006 Fri Jan  2 00:00:03 1970
Sun Mar 26 02:48:13 2006 Fri Jan  2 00:00:06 1970
Sun Mar 26 02:48:16 2006 Fri Jan  2 00:00:09 1970
Sun Mar 26 02:48:19 2006 Fri Jan  2 00:00:12 1970
Sun Mar 26 02:48:22 2006 Fri Jan  2 00:00:15 1970
Sun Mar 26 02:48:25 2006 Fri Jan  2 00:00:18 1970

上の例だと時間が決まっているばあいはいいけど、時計のようには使えない。時計にするだけなら簡単なのでここでは何秒かに1回新しく表示を切り替える時計を作ってみようと思う。

> perl -le "while(sleep 3){print scalar(localtime).qq/\a/x2;}"
Mon Mar 27 21:50:16 2006
Mon Mar 27 21:50:19 2006
Mon Mar 27 21:50:22 2006
Mon Mar 27 21:50:25 2006
Terminating on signal SIGINT(2)

3秒に1回新しい時刻を出力している。10分に1回で十分なときはsleep 600とすればいい。ついでにビープ音もならしてている。10分に1回づつ何かするけどコンピュータから目を離しておきたい場合なんかにも音で知らせてくれればありがたい。常にディスプレイとにらめっこする必要が無いからうれしい。でもストップウォッチ的に使うには多少問題外があるとおもう。精度も悪いし、操作性もよくない。

何行にも表示されてうっとうしい場合はフラッシュ($|=1)とキャリッジリターンの出力(\x0d)で解決。\rとかを使うとプラットフォームごとに異なるスクリプトにしないと使えなくなるかも。

$ perl -e '$|=1; while(sleep(1)){print scalar(localtime)."\x0d"}';

ソーシャルブックマーク

  1. はてなブックマーク
  2. Google Bookmarks
  3. del.icio.us

ChangeLog

  1. Posted: 2007-09-13T19:38:58+09:00
  2. Modified: 2007-09-13T04:10:51+09:00
  3. Generated: 2017-10-17T23:09:17+09:00