Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 将stdout和stderr捕获到文件和控制台中_Bash_Exec_Tee - Fatal编程技术网

Bash 将stdout和stderr捕获到文件和控制台中

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 >

我试图制作一个脚本,在控制台上显示状态,并制作一个日志文件。为此,我在bash脚本中使用了以下行:

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:好的,调整了措辞。谢谢解释。