如何让通过Shebang运行的Lisp脚本正常加载使用Quicklisp
问题根因
SBCL 带 --script 参数运行脚本时,默认会跳过所有系统、用户级的Lisp初始化文件(也就是不会读取 ~/.sbclrc 这类配置文件),设计目的是避免本地用户自定义配置干扰脚本运行,保证执行环境干净。
你之前执行 (ql:add-to-init-file) 只是把Quicklisp的加载逻辑写入了用户初始化文件,交互式启动SBCL时会自动加载这部分配置,但--script模式下初始化文件被跳过,Quicklisp以及其配套提供的ASDF、UIOP组件都没有被加载到环境里,自然会报找不到组件的错误。
你手动敲命令运行时显式加了 --load ~/quicklisp/setup.lisp 参数,相当于在执行脚本前手动把Quicklisp环境加载进来了,所以能正常跑通。
解决方法
按自己的使用场景选就行:
- 适合脚本分发的方案(推荐):直接在脚本开头显式加载本地Quicklisp配置,不依赖用户本地的SBCL初始化配置,脚本拷到其他装了Quicklisp的机器上也能正常跑。注意用标准API拼接home目录路径,比直接写
~兼容性更好,适配所有Common Lisp实现:
只要加载了Quicklisp的setup文件,它会自动把ASDF、UIOP的路径配置好,不需要额外执行#!/usr/bin/env sbcl --script ;; 加载Quicklisp环境 (load (merge-pathnames "quicklisp/setup.lisp" (user-homedir-pathname))) ;; 后续写业务代码即可(ql:quickload "asdf"),这步是多余的。 - 本地自用快捷方案:修改shebang行,让SBCL跑脚本时主动加载用户初始化文件,不用每个脚本都重复写加载逻辑。注意给env加
-S参数支持多参数传递,目前主流Linux、macOS的新版本都支持这个写法:
这个方案的缺点是强依赖本地#!/usr/bin/env -S sbcl --userinit ~/.sbclrc --script~/.sbclrc里已经配好了Quicklisp,脚本拷到其他没做对应配置的机器上会直接运行失败,只适合自己本地用的小脚本。
内容的提问来源于stack exchange,提问作者myTerminal
相关产品推荐
相关产品推荐

