2016-06-09 74 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的大部分實現,並可用於執行腳本或轉儲調用腳本內容的可執行文件(加載速度更快)。