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

时间:2013-08-21 07:22:50

标签: shell unix exec

有没有人能用简单的例子解释shell脚本中exec命令的用途是什么?

2 个答案:

答案 0 :(得分:260)

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

exec替换当前流程中的当前程序,而不fork新流程。在你编写的每个剧本中都不会使用它,但它偶尔会派上用场。以下是我使用过的一些场景;

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

     exec appln-program
    

    所以现在没有shell可以回去了。即使appln-program崩溃,最终用户也无法访问shell,因为它不存在 - exec取代了它。

  2. 我们想在/ etc / passwd中使用不同的shell。看起来很愚蠢,有些网站不允许用户更改他们的登录shell。我知道的一个网站上的每个人都以csh开头,每个人都只是在.login(csh启动文件)中调用ksh。虽然这样做有效,但它会使一个流浪csh进程运行,并且注销是两个阶段,可能会让人感到困惑。所以我们将它更改为exec ksh,它刚刚用korn shell替换了c-shell程序,并使一切变得更简单(还有其他问题,例如ksh不是登录的事实-shell)。

  3. 只是为了保存流程。如果我们打电话给prog1 -> prog2 -> prog3 -> prog4等并且永远不会回去,那么让每个电话都成为一名执行官。它节省了资源(不可否认,除非重复这些资源),并使关闭变得更加简单。

  4. 你显然已经看到exec在某个地方被使用了,也许如果你展示了那些惹恼你的代码,我们可以证明它的合理性。

    编辑:我意识到上面的答案是不完整的。 execksh等shell中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"
    

    read -u上使用print -ubash的ksh时,有几种方法可以使用这些方法,例如:

    read <&3
    echo stuff >&4
    

答案 1 :(得分:36)

只是为了通过简短的新手友好的简短答案来增加接受的答案,您可能不需要exec

如果你还在这里,下面的讨论应该有希望揭示原因。当你跑步时,比方说,

sh -c 'command'

运行sh实例,然后启动command作为该sh实例的子项。 command完成后,sh实例也会完成。

sh -c 'exec command'

运行sh实例,然后sh二进制替换<{em} command实例,然后运行它。

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

command

在某些边缘情况下,您希望shell读取其配置文件,或以某种方式将环境设置为运行command的准备。这几乎是exec command有用的唯一情况。

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

这会为环境做准备,以便它包含所需的内容。完成后,不再需要sh实例,因此只需用sh进程替换command实例即可进行(次要)优化,而不是sh将它作为子进程运行并等待它,然后在它完成后立即退出。

同样,如果要在shell脚本结束时为尽可能多的命令释放尽可能多的资源,您可能希望将exec该命令作为优化。

如果有什么东西强迫你运行sh但是你真的想要运行其他东西,那么exec something else当然是一种替代不受欢迎的sh实例的解决方法(例如,如果你真的想要运行你自己的漂亮gosh而不是sh,但你的/etc/shells中没有列出你的,所以你不能将它指定为你的登录shell。

第二次使用exec来操作文件描述符是一个单独的主题。接受的答案很好地涵盖了这一点;为了保持这种自包含,我只需按照手册中的exec后面跟着重定向而不是命令名。