Shellyを使ってCommon LispファイルをExecutableにする
コマンドラインからCommon Lispの関数を実行できる Shellyを使ってCommon Lispファイルを実行形式にしてみました。Shellyは
$ shly + 1 2
3
みたいに関数を実行できます。
モチベーションとしては、 Shellyの作者深町さんがTwitterで「Shellyでloadを使うとスクリプトみたいに実行できる」と発言していたのがきっかけで、Shebangを無視できればUNIX系ではExecutableにできるのでは?と思いついてやってみました。
read
してeval
して…とか考えてましたが、load
にstream
を渡せるようなので案外簡単にできました。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(in-package :shelly) | |
(export (defvar *argv* nil)) | |
(in-package :cl-user) | |
(defun script (file argv) | |
"Execute a file as script ignoring shebang" | |
(setf shelly:*argv* argv) | |
(let* ((in (open file :if-does-not-exist :error)) | |
(first-char (read-char in)) | |
(second-char (read-char in))) | |
(cond | |
((and (char= first-char #\#) (char= second-char #\!)) | |
(read-line in)) | |
(t (unread-char second-char in) | |
(unread-char first-char in))) | |
(load in) | |
(values))) |
コマンドライン引数を受け取るために*argv*
という変数を用意してます。
こんなことを~/.shelly/Shellyfile
に書いておき、Lispの初期化ファイルに
#+shelly
(load "~/.shelly/Shellyfile")
と書いてます。この~/.shelly/Shellyfile
にはShelly向けの関数を溜め込んでいく予定です。
あとは
1 2 3 4 5 |
|
をfoo.lisp
に書き込めば
$ chmod u+x foo.lisp
$./foo.lisp κeen
Hello κeen
と実行できます。勿論、
$shly script foo.lisp κeen
としても同じです。一部の処理系ではこのようなことが出来ますが、コマンドライン引数の渡し方とかも処理系依存なのでポータブルに書くなら一つ試してみてはいかがでしょうか。