包装脚本中 exec 的原因

包装脚本中 exec 的原因

我见过包装脚本示例,简而言之如下:

#!/bin/bash

myprog=sleep
echo "This is the wrapper script, it will exec "$myprog""

exec "$myprog" "$@"

如上所示,他们exec几乎立即用$myprog.无需以下条件即可实现相同目标exec

#!/bin/bash

myprog=sleep
echo "This is the wrapper script, it will exec "$myprog""

"$myprog" "$@"

在最后一个示例中,启动了一个新的 bash 实例,然后$myprog作为该 bash 实例的子进程启动。

第一种方法有什么好处?

答案1

使用exec使得包装器更加透明,即,它使得调用脚本的用户或应用程序不太可能需要知道它是依次启动“真实”程序的中继。

特别是,如果调用者想要终止该程序,他们只会终止刚刚启动的进程。如果包装器脚本运行子进程,调用者需要知道他们应该找出包装器的子进程并杀死它。包装器脚本可以设置陷阱来中继某些信号,但这不适用于无法捕获的 SIGSTOP 或 SIGKILL。

调用exec还可以节省一些内存(以及其他资源,例如 PID 等),因为无需保留额外的 shell,无需做任何事情。

如果有多个包装器,问题就会增加(难以找到要终止的正确进程、内存开销等)。

一些 shell(例如 Korn shell)会自动检测命令何时是最后一个并且没有活动陷阱并放置一个隐式exec,但并非所有 shell 都会这样做(例如不是 bash)。

答案2

没有发现重复项...请参阅FreeBSD手册,这给出了足够充分的理由:

exec语句用指定的程序替换shell进程。如果exec省略,程序执行时 shell 进程保留在内存中,并且无谓地消耗系统资源。

这本质上是很久以前(由一位搬运工)向我解释的原因,而且是众所周知的。

相关内容