Gaucheでシェルスクリプト的な何かを書くための、キモいツール書いた

Gaucheってそのままだとシェルスクリプト的なものををちょっと書いたりする用途にはあんまり向いてなくて、普通にシェルスクリプト書いたりruby使ったりしてたんだけど、そろそろgaucheでやりたいじゃん、という気分になってきた。用途からすると、似たようなライブラリを誰か書いていてもいい気がするけれど、調べるのも面倒なので自分で書いてみた。ついでにそのライブラリをデフォルトで利用できる状態にした上に、初期化ファイルを読みこんでgoshを起動するgoshellというコマンドをつくった。

まず、予め使いたいシェルのコマンドを $HOME/.goshellrc に登録する。とりあえず mkdir, ls, wget あたりを登録するときは、こんな感じ。

(define-commands mkdir ls wget)

さて、例えば http://foo.com/[000-999].jpg という1000個のファイルを /tmp/foo/ というディレクトリに保存するスクリプトが書きたいとしよう。その場合はこうすればいい。

$ goshell ;;; インタラクティブシェル起動
gosh> (mkdir /tmp/foo)
gosh> (dolist (i (iota 1000 0)) (let1 i (string-pad (number->string i) 3 #\0) (wget #`"http://foo.com/,|i|.jpg" -O #`",|i|.jpg")))

あるいは、ファイルにスクリプトを書いてもOK

#!/usr/local/bin/goshell

(mkdir /tmp/foo)
(dolist (i (iota 1000 0))
 (let1 i (string-pad (number->string i) 3 #\0)
       (wget "http://foo.com/,|i|.jpg" -O #`"/tmp/foo/,|i|.jpg")))

foo.scmという名前で保存したら

$ goshell foo.scm

で実行できる。あるいは実行属性をつければ、そのままコマンドとして実行もできる。

このライブラリのキモいところは、マクロを使ってシェルのコマンドに対応するマクロを生成して、シェルにコマンドを書く感覚でコマンドを実行できるようにしたところ。define-commandsマクロを使うことで、呼び出せるコマンドを動的に追加することももちろん可能。

gosh> uname
*** ERROR: unbound variable: uname
Stack Trace:
_______________________________________
gosh> (define-commands uname)
#<undef>
gosh> (uname -a)
("Linux haya-ubuntu 2.*.**-*-generic #1 SMP Tue Feb 12 07:42:25 UTC 2008 i686 GNU/Linux")