如何包装命令以使脚本而不是其子脚本显示为可执行文件?

如何包装命令以使脚本而不是其子脚本显示为可执行文件?

我包装了 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 "$@"

相关内容