“exec”命令有什么作用?

我不明白bash命令exec 。 我已经看到它在内部脚本中使用将所有输出重定向到一个文件(如下所示)。 但我不明白它是如何工作的或一般的。 我已阅读了手册页,但我不理解它们。

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 > filecommand > file的输出将写入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 

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

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

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

  • 如果作为第一个参数传递的命令不存在,则当前shell(不仅是exec命令)退出时出错。

  • 如果命令存在且可执行,则它将替换当前shell。 这意味着如果exec出现在脚本中,exec调用之后的指令将永远不会被执行 (除非exec本身在子shell中)。 exec永远不会回来。

  • 如果没有传递参数, exec仅用于重新定义当前的shell文件描述符。 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命令不会被执行。

要了解exec您需要先了解fork 。 我试图保持简短。

  • 当你来到路边的叉子时,你通常有两种选择。 Linux程序在遇到fork()系统调用时会到达这个分支。

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

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

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. 

exec是一个shell内置 exec ,它是G_P所说的 系统调用的exec系列的shell等价物(以及你看起来读过它的manpages)。 如果没有指定命令,它只具有影响当前shell的POSIX强制function。