如何包裝命令以使腳本而不是其子腳本顯示為可執行檔?

如何包裝命令以使腳本而不是其子腳本顯示為可執行檔?

我包裝了 R 腳本/usr/lib/R/bin/exec/R以限制記憶體使用:我將其重命名為/usr/lib/R/bin/exec/R_orig,然後創建了一個/usr/lib/R/bin/exec/R以內容命名的 bash 腳本:

#!/bin/bash
echo "Memory limited to 10G"
ulimit -Sv 10000000 #limit memory for 64-bit version
/usr/lib/R/bin/exec/R_orig "$@"

這是我對該特定程式的體驗的巨大改進,但我發現它的某些部分實際上使用可執行檔名稱來確定套件安裝路徑,並且由於可執行檔名稱被修改,因此它們失敗。

是否可以使我的腳本/usr/lib/R/bin/exec/R本身被視為可執行檔 - 例如,top不顯示單獨的子進程R_orig,而僅顯示進程R

答案1

不要那樣做。透過將原始內容替換R為將字串輸出到標準輸出的內容,您很可能會混淆可能解析其輸出的應用程式。

相反,使用新名稱建立包裝器腳本並保留原始R可執行檔不變。不要將此腳本放在/usr/lib/R/bin/exec類似的地方/usr/local/bin(如果所有用戶都需要訪問它)。這也不會混淆以後的軟體包升級或卸載腳本。

您也可以在 shell 啟動檔案中定義 shell 函數:

myR () (
    echo "Memory limited to 10G"
    ulimit -Sv 10000000 #limit memory for 64-bit version
    exec /usr/lib/R/bin/exec/R "$@"
)

另一個明顯的選擇是在 shell 初始化腳本中設定限制 ( ~/.bashrcfor bash)。此限制將延續到從 shell 啟動的任何進程。

答案2

為了希望回答您的問題,請將腳本的最後一行更改為

exec -a "$0" /usr/lib/R/bin/exec/R_orig "$@"

這將用 R_orig 程式取代目前進程(運行腳本的 shell),而不是將 R_orig 作為腳本的子進程運行。此外,它將傳遞程式的名稱,即傳統的第一個參數作為原始名稱。大多數查找軟體包安裝的程式都會使用這個名字。

我確實同意@Kusalananda 的觀點,即輸出“內存限制為 10G”訊息是一個壞主意。如果您確實想這樣做,請將其輸出到 stderr。這意味著您的腳本應該如下所示。

#!/bin/bash
echo "Memory limited to 10G" >&2
ulimit -Sv 10000000 #limit memory for 64-bit version
exec -a "$0" /usr/lib/R/bin/exec/R_orig "$@"

相關內容