わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

nowコマンドを作る

調べ物をしていて,プログラミング言語 Ruby リファレンスマニュアルというのを知りました.Ruby組み込みのTimeクラスだけでも,さまざまなことができますが,require "time"とすることで,文字列からTimeオブジェクトを作るクラスメソッドTime.parseや,Webやメールなどで即使える文字列を返すTimeのインスタンスメソッドが利用可能になります.
irbで確認しておきましょう.

$ irb
>> puts Time.now.httpdate
NoMethodError: undefined method `httpdate' for Thu Jan 15 04:36:18 +0900 2009:Time
        from (irb):1
>> require "time"
=> true
>> puts Time.now.httpdate
Wed, 14 Jan 2009 19:36:27 GMT
=> nil
>> puts Time.now.rfc2822 
Thu, 15 Jan 2009 04:36:38 +0900
=> nil
>> puts Time.now.iso8601
2009-01-15T04:36:46+09:00
=> nil

へえ,結構違うもんだ.
ではzshのfunctionにしてしまいましょう.

function now() {
    case ${1:-_} in
    -h*|--h*) # now --help
	echo usage: now '[date|httpdate|rfc2822|iso8601]' ;;
    d*) # now date
	LC_ALL=C date ;;
    h*) # now httpdate
	ruby -e 'require "time"; puts Time.now.httpdate' ;;
    i*|x*) # now iso8601, now xmlschema
	ruby -e 'require "time"; puts Time.now.iso8601' ;;
    r*) # now rfc2822, now rfc822
	ruby -e 'require "time"; puts Time.now.rfc2822' ;;
    *) # now
	ruby -e 'require "time"; puts Time.now' ;;
    esac
}

昔のシェルスクリプトで,caseを使うときは,「x$変数」のように書いて*1,「$変数」が空(未定義)のときにも対応できるようにしていた,という記憶があるのですが,zshで同じようにすると,「1: parameter not set」と出ました.
ここの1は,コマンドライン引数の1番目,すなわち(参照時には)「$1」と書くことになる変数のことです.
コマンドライン引数の1番目があればそれを,なければまあ適当に「_」とすることにしまして,変数置換演算子の「${変数名:-文字}」*2を使って書きました.
動作確認は省略.
bashでも,そのまま使えました.

*1:それと,条件分岐は「x-h*|x--h*)」や「xd*)」や「x*)」のようにします.と思ったけど最後のケースは「*)」でもいいですね.

*2:zsh最強シェル入門』, p.84