exec脚本在shell脚本中有什么用处?

任何人都可以用简单的例子来解释exec命令在shell脚本中的用法吗?

exec内置命令镜像内核中的函数,有一个基于execve ,通常从C调用。

exec取代当前进程中的当前程序,而不需要新build一个进程。 你写的每一个脚本都不是你要使用的东西,但它偶尔也派上用场。 以下是我用过的一些场景。

  1. 我们希望用户在不访问shell的情况下运行特定的应用程序。 我们可以在/ etc / passwd中更改login程序,但也许我们希望从启动文件中使用环境设置。 所以,在(说) .profile ,最后的声明说:

      exec appln-program 

    所以现在没有可以返回的shell了。 即使appln-program崩溃,最终用户也无法进入shell,因为它不在那里 – exec被replaceexec了。

  2. 我们想要在/ etc / passwd中使用一个不同的shell。 看起来很愚蠢,一些网站不允许用户改变他们的loginshell。 我知道的一个站点每个人都从csh开始,每个人.login在他们的.login (csh启动文件)中调用ksh 。 虽然这样做,它留下了一个stream浪的csh进程运行,注销是两个阶段,可能会混淆。 所以我们把它改成了exec ksh ,它用korn shell代替了c-shell程序,并且简化了一切(还有其他的问题,比如ksh不是loginshell)。

  3. 只是为了保存过程。 如果我们调用prog1 -> prog2 -> prog3 -> prog4等,永远不会回去,然后使每个调用一个exec。 它节省了资源(没有太多,坦率地说,除非重复),并使关机更简单。

你很明显看到exec在某个地方使用,也许如果你显示的代码搞砸你,我们可以certificate它的用途。

编辑 :我意识到我上面的答案是不完整的。 在像kshbash这样的shell中有两个用于exec用途 – 用于打开文件描述符。 这里有些例子:

 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号码和redirect符号之间放置一个空格,那么exec会恢复到原来的含义:

  exec 3 < thisfile # oops, overwrite the current program with command "3" 

有几种方法可以使用这些,例如在ksh上使用read -uprint -u

 read <&3 echo stuff >&4 

只是用一个简短的新手友好的简短答案来增加接受的答案,你可能不需要exec

如果你还在这里,下面的讨论应该希望揭示为什么。 当你跑步时,

 sh -c 'command' 

你运行一个sh实例,然后作为该sh实例的一个子sh启动command 。 当command结束时, sh实例也完成。

 sh -c 'exec command' 

运行sh实例,然后 command二进制代替 sh实例,然后运行它。

当然,在这个有限的背景下,这两者都是无用的。 你只是想要

 command 

有一些额外的情况,你希望shell读取它的configuration文件或以某种方式设置环境作为运行command的准备。 这几乎是exec command有用的唯一情况。

 #!/bin/sh ENVIRONMENT=$(some complex task) exec command 

这做一些东西来准备环境,以便它包含所需的东西。 一旦完成, sh实例就不再需要了,所以只需简单地用command进程replacesh实例就可以(小)优化,而不是将其作为subprocess运行并等待它,然后尽快退出当它完成。

同样,如果要在shell脚本的最后释放尽可能多的资源,可能需要将该命令作为优化执行。

如果有东西强迫你运行sh但是你真的想运行其他东西,那么exec something else当然是一个解决方法来replace不需要的sh实例(例如,如果你真的想运行自己的spiffy gosh而不是sh但是你的不是没有在/etc/shells列出,所以你不能指定它作为你的loginshell)。

exec对操作文件描述符的第二次使用是一个单独的主题。 接受的答案很好地覆盖了这个问题。 为了保持这种独立性,我只要按照exec来跟随redirect而不是命令名的任何东西,都可以遵循手册。