【问题标题】:Explain the bash command "exec > >(tee $LOG_FILE) 2>&1"解释 bash 命令“exec > >(tee $LOG_FILE) 2>&1”
【发布时间】:2023-03-03 14:47:01
【问题描述】:

我的意图是让我的 bash 脚本的所有输出显示在控制台上并记录到一个文件中。

这是我的脚本,按预期工作。

#!/bin/bash

LOG_FILE="test_log.log"
touch $LOG_FILE

# output to console and to logfile
exec > >(tee $LOG_FILE) 2>&1

echo "Starting command ls"
ls -al
echo "End of script"

但是我不明白为什么它会这样工作。

我希望exec >>(tee $LOG_FILE) 2>&1 可以工作,但它失败了,尽管exec >>$LOG_FILE 2>&1 确实可以工作。

我在bash manualadvanced bash scripting 中都找不到构造exec > >(command ) 的原因。你能解释一下它背后的逻辑吗?

【问题讨论】:

    标签: bash exec io-redirection


    【解决方案1】:

    >(tee $LOG_FILE)进程替换 的一个示例,您可能希望搜索它。 Advanced Shell ScriptngBash manual

    使用语法,<(program) 用于捕获输出,>(program) 用于提供输入,我们一次只能传递一条记录。它比命令替换(反引号或$( ))更强大,因为它替换的是文件名,而不是文本。因此,在通常指定文件的任何地方,我们都可以替换程序的标准输出或输入(尽管输入上的进程替换并不常见)。 这在程序不使用标准流来满足您的需求时特别有用。

    请注意,在您的示例中,您缺少空格,exec >>(tee $LOG_FILE) 2>&1错误(您将收到语法错误),

    exec > >(tee $LOG_FILE) 2>&1
    

    是正确的,空间很关键。

    因此,exec > 部分更改了文件描述符 1(默认值),也称为 stdout标准输出,以引用“接下来发生的事情”,在这种情况下是进程替换,尽管通常它是一个文件名。

    2>&1 重定向文件描述符 2、stderr标准错误 以引用与文件描述符 1 相同的位置(如果您省略 & 您最终会得到一个名为1)。

    一旦你这样做了,那么你就改变了当前进程的标准输出,所以接下来的命令的输出会转到那个tee进程。

    【讨论】:

    • 我已经在多个帖子中看到了该命令,但无论我尝试什么,它都对我不起作用。我不知道我错过了什么。我不断收到错误:``` 意外标记附近的语法错误`>' ```有人知道我错过了什么吗?
    • 啊,我发现哪里出错了。我用“sh ”调用脚本(包含命令)。当我使用“bash ”时它可以工作。该脚本以“#/bin/bash”开头,我认为这将使用 Bash 运行脚本,但我想我仍然需要学习一些有关 unix 中的 shell 脚本的知识:)。
    • @Kenny #! 前缀(我认为缺少的 ! 是一个错字)如果您在命令行上指定 shell,则会被视为注释。 shbash 不同。在某些平台上,/bin/sh 是到/bin/bash 的符号链接,但bash 很聪明,如果它以这种方式运行,它会尝试表现得像sh(程序可以找出哪个名称被用来调用它)。
    • @cdarke 这确实是一个错字 :) 感谢您的澄清,真的很有帮助!
    猜你喜欢
    • 2012-02-11
    • 1970-01-01
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-21
    相关资源
    最近更新 更多