gsl*_*gsl 8 lisp common-lisp command-line-interface swank
如何从命令行与本地长时间运行的Common Lisp映像(可能是守护进程)进行交互?
我知道可以从终端命令提示符运行Common Lisp函数,我也知道这一点.
我需要做类似的事情,但是使用本地的,已经长时间运行的 Common Lisp映像,能够从CLI或shell脚本中轮询可用的函数.
有没有办法从CLI执行此操作,例如从bash脚本调用函数,并接收函数返回的任何内容?
例如,我可以创建一个原始的Web服务,可能使用woo或Hunchentoot,调用函数并通过curl或获取返回值wget,但感觉有点复杂.
当然,这是Emacs的SLIME的众多功能之一,但我需要从CLI调用函数,而不需要调用Emacs.
也许有一种方法可以在SLIME之外达到一个swank后端?
如果可能的话,那会是什么样的lisp惯用方法呢?
我会感激任何指针.
许多年前,我对能够远程运行长期运行的LISP图像感到好奇(我相信在这种情况下,大写名称应该没问题).如果我没记错的话,可以在prompt.franz.com上找到.一篇文章,以某种方式连接:telnet用于远程访问正在运行的应用程序
Telnet当然是非常不安全的,但无论出于何种原因,能够以这种方式访问Lisp应用程序的用处都不能过分夸大,至少对某些人来说是这样.
我要感谢Basile Starynkevitch的精心和彻底的答案,特别是在理论方面.我正在寻找一个更实用的方向,特别是连接到Common Lisp.不过,他的回答非常有启发性.
我已准备好开始编写本地服务器,可能使用一个优秀的Common Lisp库,例如:
但是,多亏了Stanislav Kondratyev,我没有必要.他指出了一个已经存在的解决方案很好地回答了我的问题,ScriptL:Shell脚本编写了类似Lisp的问题
我在Linux,FreeBSD和OS X上成功测试了它,只需确保首先在POSIX系统调用上安装瘦包装器.在许多功能(参见自述文件)中,它允许公开所选功能,正确处理安全性,甚至提供自定义C客户端,它作为ASDF加载操作的一部分构建,并支持许多新功能,例如I/O代替netcat.
您可能会发现scriptl很有用:http://quickdocs.org/scriptl/ .但是,它依赖于iolib,它取决于一些非标准的C或C++库,因此构建它并不是很直接.
如果您熟悉swank协议,确实可以与swank服务器通信,该协议似乎未被记录(参见例如:https://github.com/astine/swank-client/blob/master/swank-description .markdown).但是,这会在网络上暴露TCP套接字,这可能是不安全的.一旦我尝试了,但我对IPC速度不满意.
前段时间我写了一个相当幼稚的SBCL专用服务器,它使用本地域套接字进行通信,使用C语言中的客户端.这是非常原始的,但你可以看看:https://github.com/quasus/lispserver.特别是,它支持交互式IO和退出代码.服务器和客户端构成了部署Unix风格软件的简单框架的核心.随意借用代码和/或与我联系以获得解释,建议等.
它当然是特定于操作系统的,因为您需要一些进程间通信,它们由操作系统提供.
假设您有一个类似OS 的POSIX,例如Linux.
然后你可以设置一个socket(7)或fifo(7),你要发送s-exprs进行评估.当然,您需要调整Common Lisp程序来添加这样的REPL.
SBCL有一些网络设施,你可以建立它们.
当然,您应该首先了解IPC如何在您的操作系统上运行.如果它是Linux,你可以阅读高级Linux编程(它以C编程为中心,这是在POSIX上使用OS服务的低级方法,但你可以调整你学到的东西到SBCL).事实上,Common Lisp标准可能没有官方的POSIX接口,因此您需要深入了解特定于实现的细节.
也许您应该了解有关BSD套接字的更多信息.有很多关于它们的教程.然后你可以使用TCP套接字(参见tcp(7))或Unix 套接字(参见unix(7)).高级用户可以使用unsafe telnet命令.或者您可能会使您的软件使用SSL,或者某些libssh,例如ssh 用作他们的客户端.
您可以决定并记录用户应用程序与您的程序之间的协议:将some-sexpr(在文档化的套接字上)从用户应用程序代码发送到您的服务器,该服务器由双换行符或换页符终止,并让您的服务器eval并发送回结果或一些错误消息.我在MELT中做了类似的事情并没有什么大不了的.小心缓冲.
我猜你认为你有负责任和称职的用户(所以不要打开这样的远程REPL到野外的互联网!).如果您关心恶意或愚蠢使用远程REPL,它就变得复杂了.
或者,使您的服务器成为Web应用程序(通过在其中使用一些HTTP服务器库),并要求用户使用他们的浏览器或某个HTTP客户端程序(curl)或库(libcurl)与其进行交互.