以编程方式检测已安装的 Common Lisp 实现

Detecting an installed Common Lisp implementation programmatically

我正在编写一个 Common Lisp 应用程序。我想要一个 Bash 脚本作为应用程序的入口点。目前,我已经编写了脚本,以便用户必须将 Common Lisp 实现的名称传递给 运行 它,所以我会为 GNU CLISP 编写 ./script.sh clisp 但使用 SBCL 的人必须编写./script.sh sbcl。这是必要的,因为与 Python 和 Ruby 等语言不同,Common Lisp 实现没有任何标准名称或调用它们的标准化方法。

是否有任何技巧可以检测安装了哪个 Common Lisp 实现,也许是环境变量或其他东西?基本上,我正在寻找比强制用户传递实现名称更好的东西。

TL;DR:我不认为有什么技巧,但您不需要在每次调用时都需要 clisp 解释器。


这是一个相对常见的模式:你有一个 bash 脚本,它依赖于某个可用的 executable,它很可能可用,但在不同的位置,可能与用户有自己的编译版本 and/or 系统有多种选择。

我看到的方法归结为这个算法:

  1. 如果有一个环境变量指定了 execu 的完整路径table,更喜欢
  2. 否则,如果用户主目录中有配置文件指定位置,可能还有其他参数,则更喜欢
  3. 否则,如果 /etc 中有指定位置的配置,可能还有其他参数,则更喜欢
  4. 否则,要求系统包管理器列出与您的应用程序的典型安装名称相匹配的包

前三个很容易使用 bash 测试函数来实现,我猜,如果你做到了这一点,你就知道如何去做了。 (如果没有,请询​​问,我会 post 个示例。)

有趣的是第四点。有两个变量需要处理。首先,确定安装环境中的包管理器。这些并不缺乏,我已经看到了 table 方法(将 OS 映射到包管理器)和查询方法(寻找与预期名称匹配的 executable,例如 rpmyumemerge 等)。其次,确定适合您的包管理器的包名称。这也可能很棘手。一方面,您可能安全地遍历已知 executable 列表并搜索列表。另一方面,您的包管理器可能会提供 "virtual" 或 "alternative" 包,这些包通常提供服务,而不管具体实现如何。例如,您可以 grep dev-lisp 的 portage 树,并有理由确保找到一个已安装的软件包。

最简单的情况是当您的脚本打算在少数知名环境中使用时 运行:实施前三点中的一个或多个,让用户覆盖脚本的自动-selection,然后您的脚本的自动选择只会迭代您已知环境中的已知替代方案,直到找到它喜欢的一个。

困难的情况是您必须支持多种环境。您最终编写了一个抽象层,该层了解不同的可能包管理器以及如何在通用级别或特定包中为各种包查询这些包系统。为部署在 AIX、HP-UX、Solaris、几个 Linux 发行版和 cygwin Windows 上的脚本集完成此操作后,我可以说:不好玩。


当我读到你的问题时,你有一个脚本将分发到你无法控制其环境的不同用户的机器上。这些目标机器的唯一要求是它们有 bash 并且至少安装了一个 Common LISP 解释器。由此,我推断您无法安装任何加载程序。但是,如果您可以安装、要求或检测其他答案中提到的任何启动器的存在,那肯定会节省大量工作。

您可以使用 Roswell,它提供了在用户或调用级别设置实现的方法。您仍然需要包装脚本,但 roswell 将它们标准化。

安装 cl-launch Unix 实用程序,它实现了@bishop 的回答中描述的抽象。该实用程序将检测 Common Lisp 的大多数实现,并可用于执行脚本或转储调用脚本内容的可执行文件(加载速度更快)。