为什么有些 Linux shell 脚本使用 exec 来运行命令?

为什么有些 Linux shell 脚本使用 exec 来运行命令?

在 Linux bash 脚本中,例如:

exec /usr/lib/4.5/mono-service.exe ./AudioVideoRecorder.exe "$@"

,为什么我必须使用exec该命令而不是在没有该exec部分的情况下运行它?

答案1

简短的回答是:你不需要,但它可以节省大约1毫秒CPU 时间(在现代 CPU 上)。 (请注意,您应该exec只在脚本的末尾,因为之后不会exec运行任何内容)。

更长的答案是: Exec将当前进程的进程映像替换为您执行的可执行文件的进程映像。这意味着当您执行时,执行execing 的 shell 进程将被完全销毁并被 ed 程序取代exec。如果不这样做exec,shell 会分叉自身,在分叉中执行,并等待子进程退出,收集其返回状态,希望之后可以运行其他命令(fork+exec是标准过程新命令产生)。由于没有,这fork完全是浪费时间,您最好直接执行并节省fork时间。

对于大多数意图和目的来说,它本质上是基于进程如何在 Unices 上生成的知识的微优化。


笔记:(谢谢 伊尔卡丘)在语义上略有不同的是,生成脚本的进程是否关心可能执行的程序如何终止。如果可能执行的子进程正常退出,则执行和非执行形式是等效的,因为 shell 脚本将最后等待的退出状态转发到其自己的退出状态。但是,如果子进程因 signal 而死亡n,那么 shell 会将其转换为退出状态128+n,从而有效地丢失发出信号的信息。 (如果您确定孩子永远不会定期以退出代码退出,则信息不会丢失,>128这通常是这种情况。)。当您执行 exec 时,不再有中间人 shell,退出状态信息直接发送到执行脚本的调用者(并且保留有关子进程是否退出或收到信号的信息,因为没有中间人 shell 将其合并到退出代码)。 (看等待进程(2)了解更多信息)。

相关内容