2016-06-09 72 views
4

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

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

+0

Python/ruby​​是“标准”,因为只有一个主要实现。考虑一下Cython和co。看到在CL以外存在同样的问题 – coredump

回答

2

TL; DR:我不认为有一个窍门,但你不需要每次调用都需要clisp解释器。


这是一种比较常见的模式:你有依赖于一定的可执行文件是可用一个bash脚本,它很可能是可用的,但在不同的位置,可能与该用户有自己的编译版本和/或具有多个替代方案的系统。

我见过的方法归结为这种算法:

  1. 如果有指定的完整路径可执行文件的环境变量,更喜欢
  2. 否则,如果有一个配置文件在用户的主目录,指定位置,以及可能的其他参数,更喜欢
  3. 否则,如果在/ etc配置,指定位置,以及可能的其他参数,更喜欢
  4. 否则,要求系统PAC卡格经理列出匹配的应用程序的典型安装名字

前三个包是很容易使用bash的测试功能来实现,并且我猜,如果你走到这一步,你知道该怎么做。 (如果没有,问,我会发布例子。)

这是第四点变得有趣。有两个变量需要处理。首先,确定安装环境中的软件包管理器。这些并不缺少,我已经看到了两种表方法(将操作系统映射到程序包管理器)和查询方法(寻找匹配预期名称的可执行文件,如rpm,yum,emerge等)。其次,确定适合您的软件包管理器的软件包名称。这也可能是棘手的。一方面,您可能会安全地遍历已知可执行文件的列表并刷新列表。另一方面,无论具体实现如何,您的软件包管理器都可以提供通常提供服务的“虚拟”或“替代”软件包。例如,你可以grep portash树的dev-lisp,并且可以合理地确定找到一个已安装的软件包。

最简单的情况是,当您的脚本是为了在少数知名环境中运行时:实现前三个点中的一个或多个以让用户覆盖脚本的自动选择,然后您的脚本的自动选择只是遍历已知环境中的已知选项,直到找到它所喜欢的选项。

当您不得不支持多种环境时,最难的情况就是如此。您最终编写了一个抽象层,该层知道可能的不同软件包管理器以及如何针对各种软件包查询这些软件包系统,无论是通用级还是特定软件包。在AIX,HP-UX,Solaris,几个Linux发行版以及cygwin Windows上部署的脚本集完成此操作后,我可以说:没什么乐趣。


当我看到你的问题时,你有一个脚本,将分发给你不控制的环境的不同用户的机器。这些目标机器的唯一要求是它们有bash并且至少安装了一个Common LISP解释器。从这里,我推断你不能安装任何装载机。但是,如果您可以安装,需要或检测其他答案中提到的任何发射器,那肯定会节省大量工作。

+0

这几乎是我正在寻找的东西,也是我害怕的东西。然后,我将开始与包管理者一起讨论。 –

+0

祝你好运!这些脚本最终会变得非常“不稳定”(如在执行大量测试中)。我发现使用具有许多小功能的bash库来做小工作使其更容易管理。我个人使用[bashworks](https://github.com/bishopb/bashworks)。 – bishop

4

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

4

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