从终端命令提示符运行Common Lisp函数

joh*_*ers 13 lisp sbcl common-lisp

我很难找到答案,所以也许这是不可能的.我希望能够灵活地从命令行加载/编译lisp文件,即不在emacs内部,然后还可以从命令行运行该文件中的一个lisp函数.这无疑是实现特定的功能,因此任何提供此功能的实现的指针(或者它可能是相当标准的,我不知道).我正在使用SBCL并喜欢它,所以如果可以做到这一点会很棒.

我也在使用Mac OSX和终端.

Jos*_*lor 22

SBCL手册描述了三个有用的选项

3.3.1运行时选项

--noinform
在启动时禁止打印任何横幅或其他信息性消息.这使得编写在Unix管道中干净利落的Lisp程序变得更加容易.另请参阅--noprint--disable-debugger选项.

3.3.2 Toplevel选项

--eval command
执行任何初始化文件后,但在标准输入上启动read-eval-print循环之前,请读取并评估给定的命令.--eval可以使用多个选项,并且将按照它们在命令行中出现的顺序读取和执行所有选项.

--load filename
这相当于--eval '(load "filename")'.特殊语法旨在减少从shell脚本调用SBCL时的引用问题.

给定一个test.lisp包含内容的文件

(defun hello-world ()
  (print 'hello-world)
  (terpri))
Run Code Online (Sandbox Code Playgroud)

我们可以用SBCL做到这一点:

$ sbcl --noinform --load test.lisp --eval '(progn (hello-world) (sb-ext:quit))'

HELLO-WORLD 
Run Code Online (Sandbox Code Playgroud)

(progn ... (sb-ext:quit))可确保程序运行结束后(hello-world).否则你会被放入SBCL提示符.由于代码是在SBCL中自动编译的,因此您运行的函数已经在运行时编译(hello-world).如果您事先编译了文件,则可以将编译后的文件传递给--load.例如,

$ sbcl --noinform --load test.fasl --eval '(hello-world)'

HELLO-WORLD 
Run Code Online (Sandbox Code Playgroud)

事实上,考虑--load到to 的等价--eval (load "filename"),你可以只使用文件名的基础,如果有编译版本,那么SBCL应该加载,如果没有,那么SBCL将加载源文件,你会得到这样编译代码.例如,在下面,我们只使用--load test:

$ sbcl --noinform --load test --eval '(hello-world)'

HELLO-WORLD 
Run Code Online (Sandbox Code Playgroud)


TW8*_*000 5

以下是第一个谷歌结果的粘贴:

克利普

如果您使用的是 CLISP Common Lisp 环境,则以下内容适用。

要将名为 test.lisp 的程序编译为名为 test.fas 的字节码文件,请执行以下操作。

clisp -c 测试.lisp

如果您希望显示更少的输出,请执行以下操作。

clisp -q -c 测试.lisp

要运行已编译(甚至未编译,如果跳过上述步骤)的 Lisp 文件,请执行以下操作,假设您的入口函数名为 main。通常,主函数的结果会在完成后显示,但 (quit) 命令会阻止这种情况。-on-error abort 选项可防止 clisp 进入调试提示符,并在出现错误时退出。

clisp -q -q -on-error abort -x '(progn (load "test") (main) (quit))'

我刚刚在我的 arch Linux 终端上测试了它,你可以执行以下操作:

$ clisp myprogram.lisp

这将直接在终端中运行该程序。如果您想编译它以供稍后运行,请参阅上面的内容。