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