cda*_*rke 271
该exec内核中的内置命令镜功能,还有他们家的基础上execve,这通常是由被称为C.
exec无需fork新流程即可替换当前流程中的当前程序.在你编写的每个剧本中都不会使用它,但它偶尔会派上用场.以下是我使用过的一些场景;
我们希望用户在不访问shell的情况下运行特定的应用程序.我们可以在/ etc/passwd中更改登录程序,但也许我们希望从启动文件中使用环境设置.所以,在(比方说)中.profile,最后一个声明说:
exec appln-program
Run Code Online (Sandbox Code Playgroud)
所以现在没有贝壳可以回去了.即使appln-program崩溃,最终用户也无法进入shell,因为它不存在 - exec取而代之.
我们想在/ etc/passwd中使用不同的shell.看起来很愚蠢,有些网站不允许用户更改他们的登录shell.我知道一个网站每个人都开始csh,每个人都只是在他们的.login(csh启动文件)中调用ksh.虽然这样做有效,但它会导致一个流浪的csh进程,并且注销是两个阶段,可能会让人感到困惑.所以我们将它更改为exec ksh刚刚用korn shell替换c-shell程序,并使一切变得更简单(还有其他问题,例如ksh不是登录shell 的事实).
只是为了保存流程.如果我们打电话prog1 -> prog2 -> prog3 -> prog4等等并且永远不会回去,那么让每个电话都成为一名执行官.它节省了资源(不可否认,除非重复),并使关闭更加简单.
你显然已经看到exec过在某个地方使用过,也许如果你展示了那些烦扰你的代码,我们可以证明它的使用是合理的.
编辑:我意识到我上面的答案是不完整的.有2只的使用exec在像炮弹ksh和bash-用于打开文件描述符.这里有些例子:
exec 3< thisfile # open "thisfile" for reading on file descriptor 3
exec 4> thatfile # open "thatfile" for writing on file descriptor 4
exec 8<> tother # open "tother" for reading and writing on fd 8
exec 6>> other # open "other" for appending on file descriptor 6
exec 5<&0 # copy read file descriptor 0 onto file descriptor 5
exec 7>&4 # copy write file descriptor 4 onto 7
exec 3<&- # close the read file descriptor 3
exec 6>&- # close the write file descriptor 6
Run Code Online (Sandbox Code Playgroud)
请注意,间距在这里非常重要.如果在fd编号和重定向符号之间放置一个空格,则exec恢复为原始含义:
exec 3 < thisfile # oops, overwrite the current program with command "3"
Run Code Online (Sandbox Code Playgroud)
有几种方法可以使用这些,在ksh上使用read -u或者print -u,bash例如:
read <&3
echo stuff >&4
Run Code Online (Sandbox Code Playgroud)
tri*_*eee 40
只是为了通过一个简短的新手友好的简短答案来增加接受的答案,你可能不需要exec.
如果你还在这里,下面的讨论应该有希望揭示原因.当你跑步时,比方说,
sh -c 'command'
Run Code Online (Sandbox Code Playgroud)
你运行一个sh实例,然后command作为该sh实例的孩子开始.当command完成后,该sh实例也结束.
sh -c 'exec command'
Run Code Online (Sandbox Code Playgroud)
运行一个sh实例,然后用二进制替换该sh实例command,然后运行它.
当然,在这种有限的背景下,这两者都是无用的; 你只是想要
command
Run Code Online (Sandbox Code Playgroud)
在某些边缘情况下,您希望shell读取其配置文件,或以某种方式将环境设置为运行准备command.这几乎是唯一exec command有用的情况.
#!/bin/sh
ENVIRONMENT=$(some complex task)
exec command
Run Code Online (Sandbox Code Playgroud)
这做了一些准备环境的东西,以便它包含所需的东西.一旦完成,sh实例就不再需要了,因此只需用进程替换sh实例就可以进行(次要)优化command,而不是将sh其作为子进程运行并等待它,然后在完成后立即退出.
同样,如果要在shell脚本结束时为尽可能多的命令释放尽可能多的资源,您可能希望exec将该命令作为优化.
如果有什么东西迫使你运行,sh但你真的想要运行别的东西,exec something else当然是一种替代不需要的sh实例的解决方法(例如,如果你真的想运行自己的漂亮gosh而不是sh你的,/etc/shells那么你就可以了不要将它指定为您的登录shell.
exec操纵文件描述符的第二个用法是一个单独的主题.接受的答案很好地涵盖了; 为了保持这种自包含,我只是按照手册中的任何地方exec,然后是重定向而不是命令名称.