从Bash内置exec的文档中考虑这一点:
exec替换了shell,而没有创建新进程
请提供一个用例/实际示例。我不明白这有什么道理。
我在Google上搜索并找到有关I / O重定向的信息。你能更好地解释吗?
从Bash内置exec的文档中考虑这一点:
exec替换了shell,而没有创建新进程
请提供一个用例/实际示例。我不明白这有什么道理。
我在Google上搜索并找到有关I / O重定向的信息。你能更好地解释吗?
Answers:
exec
通常在Shell脚本中使用,主要用作启动其他二进制文件的包装。例如:
#!/bin/sh
if stuff;
EXTRA_OPTIONS="-x -y -z"
else
EXTRA_OPTIONS="-a foo"
fi
exec /usr/local/bin/the.real.binary $EXTRA_OPTIONS "$@"
这样,在包装程序完成运行之后,“实际”二进制文件将接管,不再有临时占据进程表中同一插槽的包装程序脚本的任何痕迹。“真正的”二进制文件是启动它的任何对象的直接子代,而不是孙子代。
您在问题中还提到了I / O重定向。那是完全不同的用例,exec
与用另一个进程替换外壳无关。当exec
没有参数时,如下所示:
exec 3>>/tmp/logfile
那么命令行上的I / O重定向将在当前Shell进程中生效,但是当前Shell进程将继续运行并继续执行脚本中的下一个命令。
exec
告诉外壳程序不要在子进程中执行操作(执行命令或执行重定向),而要在同一进程中执行。
我使用了exec
内置的Shell 来获取Java程序的进程ID(PID)。现在可能有一种从Java内部获取PID的方法,但是几年前还没有。进程拥有自己的PID后,可以将其写到PID文件中(查找/var/run/
后缀为'.pid'的文件名),以允许管理程序知道正在运行的进程的PID,并防止出现第二个实例同一台服务器运行。它的工作原理如下:
exec java -cp=YourServer.jar StartClass -p $$
main()
类方法中的代码StartClass
处理参数解析,并可以找到其自己的进程ID。
为了娱乐,请在具有用户进程计费和限制的系统上在后台运行以下程序(转换为您选择的实现语言)。
while(true) fork();
现在,您被允许使用的进程表中的每个插槽都充满了该正在运行的程序的副本,您打算如何杀死它?启动kill(1)需要另一个进程插槽,而您没有。让shell用kill命令替换自己肯定很方便...
exec /bin/kill -9 -1
(假设您的系统在/ bin / kill处具有kill(1)。“ exec`which kill -9 -1”可能更安全。)这会将SIGKILL发送给您可以使用的每个进程。
(注意:除非进程限制始终允许其外壳程序有新的登录名,否则请不要从启动外壳程序注销。如果这样做,清理起来会更加困难。我当然没有在启动过程中这样做。 90年代初期。不。)
exec
在这种情况下有用的命令,则此答案会稍好一点。(2)这个答案有些陈旧;该kill
命令多年来一直是bash中的内置命令,主要是由于这种担忧。
exec
而kill
内置的事实与内置的确没有任何关系exec
。
`which kill`
)也不起作用。(2)顺便说一句,$(…)
建议使用该`…`
表格。(3)但是在目录上猜测没有任何危险。如果您不小心输入exec /binn/kill
,您只会收到一条错误消息,而您的shell也不会消失。(4)但是,你甚至都不需要什么目录的担心kill
是, exec
用途$PATH
,就像正常的命令,所以exec kill …
作品(假设你/bin
在你的搜索路径)。
这类似于Bruce需要知道进程的PID的示例:
(cmdpid = $ BASHPID;(sleep 300; kill“ $ cmdpid”)&exec long-running-command)
在你里面
(
和)
),$$
会给你的主壳的PID)。这将运行long-running-command
,但仅在预定的有限时间内进行。
这有点轻浮,但是,如果您决定要在其余的登录会话中成为root用户(或其他用户),则可以这样做exec su
。
实际上,我可以想象一个场景,在这种情况下真的很有用。假设您已登录到远程系统,并且由于某种原因,断开连接并开始新的连接存在问题。例如,假设远程系统具有遵循计划的防火墙。完成连接后,您将被允许连接,并且建立的连接不会关闭,但是目前,新连接不被接受。
您已经完成了想要做的事情,并且已经准备好注销。您的朋友Bob和您一起在房间里,他想在远程系统上做一些工作-但他无法连接。因此,您键入exec su - bob
,然后在出现密码提示时,将工作站移交给他。现在,您的UID不需要任何处理(除非您在后台运行了某些东西),因此Bob将无法处理您的文件。他将有效地接管您的联系(在您的同意和合作下)。
笔记:
su
。who
可能仍会显示您的名字。可以想象有些(写得不好)程序会使用它来认为Bob是您,并允许他访问您的资源。(a;b)
它已经与(a;exec b)
shell 相同,可以为子shell中的最后一个命令优化派生。唯一的例外似乎是bash
和mksh
。使用exec
有助于保证这一点。