“exec” 命令起什么作用?

“exec” 命令起什么作用?

我见过exec脚本中使用命令将所有输出重定向到一个文件(如)但是简单来说,它起什么作用呢?

答案1

man bash说:

exec [-cl] [-a name] [command [arguments]]
      If command is specified, it replaces the shell.  No new  process
      is  created.  The arguments become the arguments to command.  If
      the -l option is supplied,  the  shell  places  a  dash  at  the
      beginning  of  the  zeroth  argument passed to command.  This is
      what login(1) does.  The -c option causes command to be executed
      with  an empty environment.  If -a is supplied, the shell passes
      name as the zeroth argument to the executed command.  If command
      cannot  be  executed  for  some  reason, a non-interactive shell
      exits, unless the execfail shell option  is  enabled.   In  that
      case,  it returns failure.  An interactive shell returns failure
      if the file cannot be executed.  If command  is  not  specified,
      any  redirections  take  effect  in  the  current shell, and the
      return status is 0.  If there is a redirection error, the return
      status is 1.

最后两行是重点:如果你exec单独运行,而不使用命令,它只会将重定向应用于当前 shell。你可能知道,当你运行 时command > file, 的输出command将写入file而不是 到你的终端(这称为重定向)。如果您exec > file改为运行,则重定向将应用于整个 shell:shell 生成的任何输出都将写入file而不是您的终端。例如这里

bash-3.2$ bash
bash-3.2$ exec > file
bash-3.2$ date
bash-3.2$ exit
bash-3.2$ cat file
Thu 18 Sep 2014 23:56:25 CEST

我首先启动一个新bashshell。然后,在这个新 shell 中我运行exec > file,这样所有输出都重定向到file。事实上,在那之后我运行date但没有输出,因为输出被重定向到file。然后我退出 shell(这样重定向不再适用)并且我看到确实包含我之前运行的命令file的输出。date

答案2

exec是一个具有两种截然不同行为的命令,取决于是否使用至少一个参数,或者根本不使用任何参数。

  • 如果传递了至少有一个参数,则第一个参数将作为命令名,并exec尝试将其作为命令执行,将其余参数(如果有)传递给该命令并管理重定向(如果有)。

  • 如果作为第一个参数传递的命令不存在,则当前 shell(不仅是命令)exec会错误退出,除非 shell 是交互式的或者execfail设置了 bash 选项 ( shopt -s execfail)。另请参阅https://superuser.com/questions/992204/why-does-exec-non-existent-file-exits-the-shell-when-in-a-script-that-is-sourc

  • 如果命令存在且可执行,它将替换当前 shell。这意味着,如果exec出现在脚本中,则 exec 调用后面的指令永远不会被执行(除非exec它本身位于子 shell 中)。成功exec永远不会返回。类似“EXIT”的 Shell 陷阱也不会被触发。

  • 如果没有传递参数,exec则仅用于重新定义当前 shell 文件描述符。exec与前一种情况不同,shell 在 之后继续,但标准输入、输出、错误或任何已重定向的文件描述符都将生效。

  • 如果某些重定向使用/dev/null,则来自它的任何输入都将返回 EOF,并且任何输出都将被丢弃。

  • -您可以使用作为源或目标来关闭文件描述符,例如exec <&-。后续读取或写入将失败。

以下有两个示例:

echo foo > /tmp/bar
exec < /tmp/bar # exec has no arguments, will only affect current shell descriptors, here stdin
cat # simple command that read stdin and write it to stdout

该脚本将输出“foo”作为 cat 命令,而不是像通常那样等待用户输入,而是从包含 foo 的 /tmp/bar 文件中获取输入。

echo foo > /tmp/bar
exec wc -c < /tmp/bar # exec has two arguments, the control flow will switch to the wc command
cat

此脚本将显示4(/tmp/bar 中的字节数)并立即结束。该cat命令不会被执行。

答案3

要理解,exec您首先需要理解fork。我尽量简短地说。

  • 当你遇到岔路时,通常有两种选择。Linux 程序在遇到系统调用时到达岔路 fork()

  • 普通程序是系统中以编译形式存在的系统命令。执行此类程序时,会创建一个新进程。此子进程与其父进程具有相同的环境,只有进程 ID 号不同。此过程称为 分叉

  • 分叉为现有进程提供了一种启动新进程的方法。但是,在某些情况下,子进程与父进程不是同一程序的一部分。在这种情况下exec使用。exec 将用程序二进制文件中的信息替换当前正在运行的进程的内容。
  • 在分叉进程之后,子进程的地址空间将被新进程数据覆盖。这是通过对系统的 exec 调用完成的。

答案4

在 中bash,如果你这样做help exec

$ help exec
exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
    Replace the shell with the given command.

    Execute COMMAND, replacing this shell with the specified program.
    ARGUMENTS become the arguments to COMMAND.  If COMMAND is not specified,
    any redirections take effect in the current shell.

    Options:
      -a name   pass NAME as the zeroth argument to COMMAND
      -c        execute COMMAND with an empty environment
      -l        place a dash in the zeroth argument to COMMAND

    If the command cannot be executed, a non-interactive shell exits, unless
    the shell option `execfail' is set.

    Exit Status:
    Returns success unless COMMAND is not found or a redirection error occurs.

相关部分:

If COMMAND is not specified, any redirections take effect in the current shell.

execshell 内置命令,这是 shell 等同exec系统调用G_P 谈到(并且你似乎已经阅读了它的手册页)。它只是有POSIX 授权如果没有指定命令,则影响当前 shell 的功能。

相关内容