我正在尝试使用 SBCL 1.1.7 从命令行在 Ubuntu 12.04 上运行一个通用的 lisp 脚本。我开始脚本
$ sbcl --script <my-script.lisp>
由于脚本UTF_8编码,因此我收到一些错误消息:
; compiling (DEFUN PRINT-USAGE ...)unhandled SB-INT:STREAM-DECODING-ERROR in thread #<SB-THREAD:THREAD
"main thread" RUNNING
{1002A39983}>:
:ASCII stream decoding error on
#<SB-SYS:FD-STREAM
for "file ... .lisp"
{10045745E3}>:
the octet sequence #(194) cannot be decoded.
我想解决方案是告诉 SBCL 将源文件视为 UTF-8,但我在文档或谷歌上找不到有关如何执行此操作的任何内容。
有什么提示吗?
我不太喜欢 SBCL 黑客,但查看 toplevel.lisp,似乎处理--script
的代码是:
(defun process-script (script)
(flet ((load-script (stream)
;; Scripts don't need to be stylish or fast, but silence is usually a
;; desirable quality...
(handler-bind (((or style-warning compiler-note) #'muffle-warning)
(stream-error (lambda (e)
;; Shell-style.
(when (member (stream-error-stream e)
(list *stdout* *stdin* *stderr*))
(exit)))))
;; Let's not use the *TTY* for scripts, ok? Also, normally we use
;; synonym streams, but in order to have the broken pipe/eof error
;; handling right we want to bind them for scripts.
(let ((*terminal-io* (make-two-way-stream *stdin* *stdout*))
(*debug-io* (make-two-way-stream *stdin* *stderr*))
(*standard-input* *stdin*)
(*standard-output* *stdout*)
(*error-output* *stderr*))
(load stream :verbose nil :print nil)))))
(handling-end-of-the-world
(if (eq t script)
(load-script *stdin*)
(with-open-file (f (native-pathname script) :element-type :default)
(sb!fasl::maybe-skip-shebang-line f)
(load-script f))))))
看起来文件是用(with-open-file (f (native-pathname script) :element-type :default) …)
打开的。 根据usockets的答案:打开套接字时如何指定外部格式,默认编码应该是UTF-8,快速的交互式测试似乎可以确认:
CL-USER> sb-impl::*default-external-format*
:UTF-8
但是,根据处理选项的顺序,您可能能够执行的操作是在处理脚本之前使用 --eval
选项设置sb-impl::*default-external-format*
。 例如,命令行如下:
$ sbcl --eval '(setf sb-impl::*default-external-format* …)' --script my-script.lisp
但是,也就是说,我完全不确定是否支持。 根据 comp.lang.lisp 上的一个线程,如何在 SBCL 中更改外部格式(c 字符串编码错误),默认编码是通过检查环境来确定的,因此环境中可能有一些事情可以获取您需要的编码作为默认值。 该线程中的一个响应表明以下内容可能有效:
$ LC_CTYPE=en_US.UTF-8
$ export LC_CTYPE
$ sbcl --script my-script.lisp