【问题标题】:capturing both stdout and stderr into a file and also to a console将 stdout 和 stderr 捕获到文件和控制台中
【发布时间】:2013-01-30 23:14:50
【问题描述】:

我正在尝试制作一个在控制台上吐出状态的脚本并制作一个日志文件。为此,我一直在我的 bash 脚本中使用以下行:

exec > >(tee logfile.txt)

让这一行有效地在控制台上显示标准输出并将其存储到 logfile.txt 中。现在我想同时捕获标准输出和标准错误。我尝试使用

exec 2>&1 >(tee logfile.txt)

这似乎不起作用。为什么?我怎样才能完成我的任务?

【问题讨论】:

    标签: bash exec tee


    【解决方案1】:

    只需颠倒重定向的顺序。它可以帮助我从右到左阅读它们:

    exec > >(tee logifle.txt) 2>&1
    

    【讨论】:

    • 第一句话和代码片段——很好。第二句——错了!重定向从左到右解释。第一个执行“进程替换”,以便标准输出进入tee 程序。然后2>&1 将标准错误发送到标准输出当前所在的位置(tee 程序)。问题中的代码首先执行2>&1,将标准错误发送到标准输出当前所在的位置,然后进行更改,以便标准输出进入tee 进程(但标准错误,文件描述符2,仍然会去控制台)
    • @JonathanLeffler:嗯,这可能取决于人们如何解释它。对我来说,我必须先将 stderr 重定向到 stdout,然后将 stdout 重定向到 tee:否则,如果从重定向 stdout 开始,我不能稍后将 stderr 重定向到它:-) 这没有说明它是如何实现的。跨度>
    • 好吧,shell 从左到右工作。第一个重定向将文件描述符 1 (stdout) 设置为进入进程 - 创建管道等。第二个重定向等效于 dup2(1, 2); - 它将文件描述符 1 复制为文件描述符 2 (stderr),因此 stdout 和 stderr是两个单独的文件描述符 (1, 2) 指向同一个文件(管道的写入端到tee 进程)。并且以相反的顺序,shell首先执行dup2(1, 2);,以便文件描述符2引用文件描述符1所引用的位置(但独立于文件描述符1),...[继续]
    • [continuation]...然后更改文件描述符 1,使其写入到 tee 进程的管道,而不更改文件描述符 2 指向的位置(这是控制台,因为这就是文件描述符 1 在进行 dup2() 调用时所指向的位置。
    • @JonathanLeffler:好的,调整了措辞。感谢您的解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 2011-04-22
    • 2012-06-17
    • 2014-07-22
    • 2021-09-08
    • 1970-01-01
    相关资源
    最近更新 更多