sbclのスクリプトファイル作成
FreeBSD, Linuxでsbclのスクリプトファイルを作成するメモです。
長々と書きますので、結果だけを先に示します。
スクリプトファイルの1行目には次のように記載すると便利ですね。
#!/usr/bin/env -S sbcl --script
スクリプトファイルの作成
sbclには引数--script
を指定することにより、スクリプトファイルを読み込むことができます。
つまりは次のように呼び出しを行うことができます。
$ sbcl --script script-file.lisp
しかしこのオプションは、おそらく上記のようにコマンドラインで実行するためのものではなく、
スクリプトファイルに組み込んで使うものだと思います。
問題はこれをどのように記載するかです。
Unix系のOSでは、テキストファイルの1行目を#!
で開始することで、
スクリプトに渡す実行ファイルを指定することができます。
開始1byteから#
で始める必要があるので、UTF-8
のBOMありはエラーになるので注意。
例えば次の通り。
#!/usr/bin/sbcl --script (format t "Hello~%")
実行してみます。
$ cat > test.sh #!/usr/bin/sbcl --script (format t "Hello~%") ^D $ chmod +x test.sh $ ./test.sh Hello
うまく行ったならおめでとう!
でも、上記の書き方だとダメな場合があります。
sbclの場所が違う
Linuxだと/usr/bin/sbcl
ですが、FreeBSDでは/usr/local/bin/sbcl
となります。
次のように変更することで動作はします。
#!/usr/local/bin/sbcl --script (format t "Hello~%")
あるいはsymbolic linkを作成するのでもいいと思います。
# ln -s /usr/local/bin/sbcl /usr/bin/sbcl
しかしこれは問題を解決したと言えるのでしょうか?
実行ファイルの場所が違う問題は、sbcl
に限らずUnix系ではよく生じる問題です。
一般的には/usr/bin/env
を用いて解決します。
env
は実行するファイルを環境変数PATH
から探し呼び出します。
次のような記載を見たことがある人もいると思います。
#!/usr/bin/env perl ...
今の場合はperl
ではなくsbcl
ですが、
/usr/bin
も/usr/local/bin
もPATH
に登録されているのであれば、
同じように置き換えることで実行できるかもしれません。
#!/usr/bin/env sbcl --script (format t "★注意:たぶん失敗する~%")
たぶん失敗すると記載したように、これだとうまく行かないかもしれません。
どうもFreeBSD 6.0までは上記でうまく行けたようなのです。
しかし問題があったためkernelに仕様変更が生じました。
今は次のように、引数-S
を記載するのが正しいとのことです。
#!/usr/bin/env -S sbcl --script (format t "Hello~%")
これはFreeBSDだけではなくLinuxも正しく動作します。
動作確認を行う場合は、引数のチェックを含めて行った方が良いです。
例えば次のスクリプトファイルを用意します。
#!/usr/bin/env -S sbcl --script (format t "~S~%" sb-ext:*posix-argv*)
スクリプト名をtest.sh
としたときの実行結果を下記に示します。
$ ./test.sh ("sbcl") $ ./test.sh 10 20 30 ("sbcl" "10" "20" "30")
sbclに渡す引数を変更したい
スクリプトで実行するsbclの引数を変更したい場合があります。
例えば--core
を指定したい場合はどうするべきでしょうか。
$ ./test.sh --core /path/to/sbcl.core ("sbcl" "--core" "/path/to/sbcl.core")
たぶん目的とは違った結果になってしまいます。
このように、スクリプトの引数に指定しても何の解決にもなりません。
スクリプトに埋め込む
一つの方法は、スクリプトの1行目に埋め込むことです。
例えば次のようなスクリプトファイルを作成します。
#!/usr/bin/env -S sbcl --core /path/to/sbcl.core --script (format t "~S~%" sb-ext:*posix-argv*)
これはこれで良いのですが、もし移植性を考えるのであれば、 この方法は使用できないでしょう。
実行するsbclを別のものにする
例えば$HOME/bin/
上にsbcl
というスクリプトを作り、
それをPATH
に登録する方法です。
実行するsbcl
そのものを変更するため、
元々のスクリプトには手を入れる必要がありません。
ユーザーが使用するshell
によって手順が変わりますが、
今はbash
を使っているものとします。
login時にシステムが自動的に$HOME/bin
をPATH
に追加してくれるならよいのですが、
たぶん自分で設定する必要があると思います。
次の手順を実施します。
$ cd $HOME $ mkdir bin $ chmod 700 bin $ vi .bashrc 最終行に下記を追記 export PATH="$HOME/bin:$PATH" $ vi .bash_profile 次の内容を追記 if [[ -r $HOME/.bashrc ]]; then source $HOME/.bashrc fi
$ cd $HOME/bin $ touch sbcl $ chmod +x sbcl $ vi sbcl
次の内容で保存します。
#!/bin/sh /usr/bin/sbcl --core /path/to/sbcl.core "$@"
一度logoutしてからloginしなおします。
次に起動確認を行います。
$ which sbcl /home/xxx/bin/sbcl $ sbcl --version SBCL 1.4.12
引数のチェックを行ったスクリプトを用意します。
#!/usr/bin/env -S sbcl --script (format t "~S~%" sb-ext:*posix-argv*)
実行確認を行います。
$ ./test.sh ("/usr/bin/sbcl") $ ./test.sh 10 20 30 ("/usr/bin/sbcl" "10" "20" "30")
なお、.bashrc
, .bash_profile
, .profile
あたりのファイルは、
login時、bash
実行時、ssh
など外部接続時にて、
読み込まれるファイルが違ったりしますので、
必要に応じてチェックしてみてください。