如何在使用管道使用“tee”时将stderr写入文件?
我有一个命令,它会将aaa.sh
的输出打印到屏幕上,同时将stdout写入bbb.out
; 但是我也想写一个名为ccc.out
的文件stderr。 有关如何修改下面的内容的任何建议?
./aaa.sh | tee ./bbb.out
更新:无论如何,stdout和stderr都应该被打印到屏幕上。
我假设你还想在终端上看到STDERR和STDOUT。 你可以去乔许·凯利的回答,但我觉得保持一个tail
在输出日志文件非常hackish的和cludgy背景周围。 注意你需要保留一个exra FD,然后通过杀死它来进行清理,并且在技术上应该在trap '...' EXIT
这样做trap '...' EXIT
。
有一个更好的方法来做到这一点,你已经发现它: tee
。
只是,不要仅仅将它用于stdout,而应该为stdout开发一个tee,为stderr开一个。 你将如何做到这一点? 进程替换和文件重定向:
command > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)
让我们分解并解释:
> >(..)
>(...)
(进程替换)创建一个FIFO并让tee
监听它。 然后,它使用>
(文件重定向)将command
的STDOUT重定向到第一个tee
正在侦听的FIFO。
第二件事情同样如此:
2> >(tee -a stderr.log >&2)
我们再次使用进程替换来创建一个从STDIN读取并将其转储到stderr.log
的tee
进程。 tee
在STDOUT上输出它的输入,但由于它的输入是我们的STDERR,我们希望再次将tee
的STDOUT重定向到STDERR。 然后我们使用文件重定向将command
的STDERR重定向到FIFO的输入( tee
的STDIN)。
请参阅http://mywiki.wooledge.org/BashGuide/InputAndOutput
过程替换是你选择bash
作为你的shell而不是sh
(POSIX或Bourne)的奖励的真正可爱的东西之一。
在sh
,你必须手动完成任务:
out="${TMPDIR:-/tmp}/out.$$" err="${TMPDIR:-/tmp}/err.$$"
mkfifo "$out" "$err"
trap 'rm "$out" "$err"' EXIT
tee -a stdout.log < "$out" &
tee -a stderr.log < "$err" >&2 &
command >"$out" 2>"$err"
为什么不简单:
./aaa.sh 2>&1 | tee -a log
这只是将stderr
重定向到stdout
,因此tee会同时回显登录和屏幕。 也许我错过了一些东西,因为其他一些解决方案似乎很复杂。
注意:由于bash版本4,您可以使用|&
作为2>&1 |
的缩写 :
./aaa.sh |& tee -a log
这可能对通过谷歌搜索此人有用。 简单地取消注释您想要尝试的示例。 当然,可以随意重命名输出文件。
#!/bin/bash
STATUSFILE=x.out
LOGFILE=x.log
### All output to screen
### Do nothing, this is the default
### All Output to one file, nothing to the screen
#exec > ${LOGFILE} 2>&1
### All output to one file and all output to the screen
#exec > >(tee ${LOGFILE}) 2>&1
### All output to one file, STDOUT to the screen
#exec > >(tee -a ${LOGFILE}) 2> >(tee -a ${LOGFILE} >/dev/null)
### All output to one file, STDERR to the screen
### Note you need both of these lines for this to work
#exec 3>&1
#exec > >(tee -a ${LOGFILE} >/dev/null) 2> >(tee -a ${LOGFILE} >&3)
### STDOUT to STATUSFILE, stderr to LOGFILE, nothing to the screen
#exec > ${STATUSFILE} 2>${LOGFILE}
### STDOUT to STATUSFILE, stderr to LOGFILE and all output to the screen
#exec > >(tee ${STATUSFILE}) 2> >(tee ${LOGFILE} >&2)
### STDOUT to STATUSFILE and screen, STDERR to LOGFILE
#exec > >(tee ${STATUSFILE}) 2>${LOGFILE}
### STDOUT to STATUSFILE, STDERR to LOGFILE and screen
#exec > ${STATUSFILE} 2> >(tee ${LOGFILE} >&2)
echo "This is a test"
ls -l sdgshgswogswghthb_this_file_will_not_exist_so_we_get_output_to_stderr_aronkjegralhfaff
ls -l ${0}
链接地址: http://www.djcxy.com/p/42693.html
上一篇: How do I write stderr to a file while using "tee" with a pipe?
下一篇: Apple rejection for black bar on top of ipad screen for an iPhone application