在 Linux bash 脚本中,例如:
exec /usr/lib/4.5/mono-service.exe ./AudioVideoRecorder.exe "$@"
,为什么我必须使用exec
该命令而不是在没有该exec
部分的情况下运行它?
答案1
简短的回答是:你不需要,但它可以节省大约1毫秒CPU 时间(在现代 CPU 上)。 (请注意,您应该exec
只在脚本的末尾,因为之后不会exec
运行任何内容)。
更长的答案是:
Exec
将当前进程的进程映像替换为您执行的可执行文件的进程映像。这意味着当您执行时,执行exec
ing 的 shell 进程将被完全销毁并被 ed 程序取代exec
。如果不这样做exec
,shell 会分叉自身,在分叉中执行,并等待子进程退出,收集其返回状态,希望之后可以运行其他命令(fork
+exec
是标准过程新命令产生)。由于没有,这fork
完全是浪费时间,您最好直接执行并节省fork
时间。
对于大多数意图和目的来说,它本质上是基于进程如何在 Unices 上生成的知识的微优化。
笔记:(谢谢 伊尔卡丘)在语义上略有不同的是,生成脚本的进程是否关心可能执行的程序如何终止。如果可能执行的子进程正常退出,则执行和非执行形式是等效的,因为 shell 脚本将最后等待的退出状态转发到其自己的退出状态。但是,如果子进程因 signal 而死亡n
,那么 shell 会将其转换为退出状态128+n
,从而有效地丢失发出信号的信息。 (如果您确定孩子永远不会定期以退出代码退出,则信息不会丢失,>128
这通常是这种情况。)。当您执行 exec 时,不再有中间人 shell,退出状态信息直接发送到执行脚本的调用者(并且保留有关子进程是否退出或收到信号的信息,因为没有中间人 shell 将其合并到退出代码)。 (看等待进程(2)了解更多信息)。