Bash 将stdout和stderr捕获到文件和控制台中
我试图制作一个脚本,在控制台上显示状态,并制作一个日志文件。为此,我在bash脚本中使用了以下行:Bash 将stdout和stderr捕获到文件和控制台中,bash,exec,tee,Bash,Exec,Tee,我试图制作一个脚本,在控制台上显示状态,并制作一个日志文件。为此,我在bash脚本中使用了以下行: exec > >(tee logfile.txt) 这一行有效地在控制台上显示stdout,并将其存储到logfile.txt中。现在我想捕获stdout和stderr。我试着用 exec 2>&1 >(tee logfile.txt) 这似乎不起作用。为什么?我怎样才能完成我的任务呢?只要颠倒重定向的顺序就行了。这有助于我从右到左阅读它们: exec >
exec > >(tee logfile.txt)
这一行有效地在控制台上显示stdout,并将其存储到logfile.txt中。现在我想捕获stdout和stderr。我试着用
exec 2>&1 >(tee logfile.txt)
这似乎不起作用。为什么?我怎样才能完成我的任务呢?只要颠倒重定向的顺序就行了。这有助于我从右到左阅读它们:
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),…[续][续]…然后更改文件描述符1,使其写入到通向tee
进程的管道,而不更改文件描述符2指向的位置(这是控制台,因为在调用dup2()
时,文件描述符1就指向了控制台。@JonathanLeffler:好的,调整了措辞。谢谢解释。