关于UNIX:exec命令在shell脚本中有什么用?

What are the uses of the exec command in shell scripts?

谁能用简单的例子解释exec命令在shell脚本中的用途吗?


内置命令exec反映了内核中的功能,其中有一系列基于execve的功能,通常从C调用。

exec替换当前进程中的当前程序,而无需fork新建一个进程。并不是您在编写的每个脚本中都会使用它,但有时会派上用场。这是我使用过的一些场景;

  • 我们希望用户在不访问外壳的情况下运行特定的应用程序。我们可以在/ etc / passwd中更改登录程序,但是也许我们希望从启动文件中使用环境设置。因此,在(例如).profile中,最后一条语句表示如下内容:

    1
     exec appln-program

    所以现在没有外壳可以回去了。即使appln-program崩溃,最终用户也无法进入shell,因为它不存在-exec替换了它。

  • 我们要使用与/ etc / passwd中不同的shell。看起来很愚蠢,有些网站不允许用户更改其登录外壳。我知道有一个站点,每个人都以csh开头,并且每个人都将对ksh的调用放入其.login(csh启动文件)中。在此过程中,它留下了一个迷离的csh进程,并且注销是两个阶段,可能会引起混淆。因此,我们将其更改为exec ksh,后者仅用korn shell替换了c-shell程序,并使一切变得更简单(与此相关的还有其他问题,例如ksh不是登录shell)。

  • 只是为了节省流程。如果我们调用prog1 -> prog2 -> prog3 -> prog4等并且从不回退,则使每个调用都执行一次。这样可以节省资源(当然,除非重复,否则可以节省很多资源),并且使关机更加简单。

  • 您显然已经看到exec在某处使用过,也许如果您显示的代码有问题,我们可以证明其使用是合理的。

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

    1
    2
    3
    4
    5
    6
    7
    8
    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还原为原始含义:

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

    有几种方法可以使用它们,例如,在ksh上,在bash上使用read -uprint -u

    1
    2
    read <&3
    echo stuff >&4


    只需使用简短的新手友好的简短答案来增加已接受的答案,您可能不需要exec

    如果您仍在这里,则以下讨论将有望揭示原因。跑步时说

    1
    sh -c 'command'

    您运行sh实例,然后将command作为该sh实例的子代启动。 command完成时,sh实例也完成。

    1
    sh -c 'exec command'

    运行一个sh实例,然后将该sh实例替换为command二进制文件,然后运行它。

    当然,在这种有限的情况下,这两者都是无用的。你只是想要

    1
    command

    在某些情况下,您希望外壳程序读取其配置文件,或者以其他方式设置环境以作为运行command的准备。这是exec command有用的唯一情况。

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

    这会做一些事情来准备环境,使其包含所需的内容。完成此操作后,就不再需要sh实例了,因此,将(x1>实例替换为command进程,而不是让sh作为子进程运行,并且是一个(次要)优化)等待它,然后在完成时退出。

    同样,如果您想在shell脚本的末尾释放尽可能多的资源来执行繁琐的命令,则可能需要exec作为优化。

    如果某些因素迫使您运行sh,但您确实想运行其他东西,则exec something else当然是一种替代方法,用于替换不需要的sh实例(例如,如果您确实想运行自己的精美gosh而不是sh,但您的用户不在/etc/shells中,因此您不能将其指定为登录外壳程序)。

    exec操纵文件描述符的第二个用途是一个单独的主题。公认的答案很好地涵盖了这一点。为了使它自成一体,对于exec后跟重定向而不是命令名称的任何内容,我将只参考本手册。