【问题标题】:I don't understand bash exec [duplicate]我不明白 bash exec [重复]
【发布时间】:2026-02-16 22:05:01
【问题描述】:
#!/bin/bash
#...
exec >> logfile
#cmd

我来宾它是保存输出。 你能用同样的例子扩展它吗? 非常感谢!

我经常用这个命令列出txt文件:

find / -type f -exec grep -l "bash" {} \;

但我也不是很明白。


世界上怎么会有这么好的人,非常非常感动!

【问题讨论】:

  • 请完善您的问题。目前,它太宽泛,难以理解
  • >> 允许您将某些内容的输出添加到文件末尾。目前“exec”结果将被添加到日志文件的末尾。
  • 感谢塞尔吉奥·伊万努佐!

标签: bash exec


【解决方案1】:

是的,它将任何进一步的输出发送到名为logfile 的文件。换句话说,它将标准输出(也称为stdout)重定向到文件logfile

示例

让我们从这个脚本开始:

$ cat >script.sh
#!/bin/bash
echo First
exec >>logfile
echo Second

如果我们运行脚本,我们会看到第一个但不是第二个 echo 语句的输出:

$ bash script.sh
First

第二个echo 语句的输出转到文件logfile

$ cat logfile
Second
$ 

如果我们使用了exec >logfile,那么每次运行脚本时logfile 将被覆盖。因为我们使用了>> 而不是>,所以输出将追加logfile。例如,如果我们再次运行它:

$ bash script.sh
First
$ cat logfile
Second
Second

文档

这记录在man bash:

exec [-cl] [-a name] [command [arguments]]
if command 已指定,它会替换 shell。不会创建新进程。这 参数成为命令的参数。如果 -l 选项是 提供时,shell 在第零个开头放置一个破折号 参数传递给命令。这就是 login(1) 的作用。 -c 选项导致命令在空环境下执行。如果 提供 -a 时,shell 将 name 作为第零个参数传递给执行的命令。如果由于某种原因无法执行命令,则 非交互式 shell 退出,除非 execfail shell 选项是 启用。在这种情况下,它返回失败。交互式外壳 如果文件无法执行,则返回失败。 如果命令不是 指定,任何重定向都在当前 shell 中生效,并且 返回状态为0。如果有重定向错误,返回 状态为 1。[强调已添加。]

在您的情况下,没有指定 command 参数。因此,exec 命令执行重定向,在这种情况下,这意味着任何进一步的标准输出都将发送到文件 logfile

查找命令和-exec

find 命令有一个-exec 选项。例如:

find / -type f -exec grep -l "bash" {} \;

除了名字相似之外,这里的-exec与shell命令exec完全没有关系。

构造-exec grep -l "bash" {} \; 告诉find 在它找到的任何文件上执行命令grep -l "bash"。这与 shell 命令 exec >>logfile 无关,后者不执行任何操作,但具有重定向输出的效果。

【讨论】:

    【解决方案2】:

    您输出到标准输出的所有内容都不会输出到标准输出,而是输出到日志文件。 请参见下面的示例:

    #!/bin/bash
    # reassign-stdout.sh
    
    LOGFILE=logfile.txt
    
    exec 6>&1           # Link file descriptor #6 with stdout.
                        # Saves stdout.
    
    exec > $LOGFILE     # stdout replaced with file "logfile.txt".
    
    # ----------------------------------------------------------- #
    # All output from commands in this block sent to file $LOGFILE.
    
    echo -n "Logfile: "
    date
    echo "-------------------------------------"
    echo
    
    echo "Output of \"ls -al\" command"
    echo
    ls -al
    echo; echo
    echo "Output of \"df\" command"
    echo
    df
    
    # ----------------------------------------------------------- #
    
    exec 1>&6 6>&-      # Restore stdout and close file descriptor #6.
    
    echo
    echo "== stdout now restored to default == "
    echo
    ls -al
    echo
    
    exit 0
    

    【讨论】:

      【解决方案3】:

      这会将您的脚本和随后调用的任何其他程序产生的标准输出重定向到logfile。因此,如果您的脚本在执行后在终端中运行

      exec >> logfile
      

      您不会在终端窗口中看到任何输出,但您会在 logfile 中找到它。如果 logfile 不存在或每次运行脚本时附加,则将创建它。

      【讨论】: