将stdout和stderr命令记录到日志文件中相当简单:
./foo.sh &> log.txt
问题在于,在检查日志文件时,人们不再知道哪一行来自哪个流。这可以通过将stdout和stderr重定向到两个单独的文件来修复,但随后输出的时间顺序和交错将丢失。
另一种解决方案是重定向到三个文件。一个是stdout,一个是stderr,另一个是两者合二为一。类似的东西:
./foo.sh 2> >(tee stderr | tee -a combined) 1> >(tee stdout | tee -a combined)
但是拥有这么多文件并不是很优雅(而且这个命令仍然会在shell上转储输出的副本)。
我发现了一个有趣的bash函数,它只会为红色的stderr消息着色:
color()(set -o pipefail;"$@" 2>&1>&3|sed $'s,.*,\e[31m&\e[m,'>&2)3>&1
但它不保留输出的顺序,结果在文本编辑器中不可读。给出foo.sh
的以下程序:
for i in 1 2; do
for j in 1 2; do
printf '%s\n' "out $i"
done
for k in 1 2; do
printf '%s\n' "err $i" >&2
done
done
运行color ./foo.sh
会产生:
out 1
out 1
out 2
out 2
[31merr 1[m
[31merr 1[m
[31merr 2[m
[31merr 2[m
如何在一个日志文件中轻松地结束这样的事情?
@| out 1
@| out 1
$| err 1
$| err 1
@| out 2
@| out 2
$| err 2
$| err 2
答案 0 :(得分:2)
也许您正在寻找script
它记录stdout,stderr和命令......它启动一个新的shell,在其中记录所有内容(或使用-c _cmd_
)
$ script tx1
您的color()
函数因为sed
正在缓冲...
答案 1 :(得分:1)
如何将stderr重定向到./tmperr并将stdout重定向到./tmpout,现在在后台运行两个脚本,每个脚本从tmperr或tmpout连续读取一行,然后删除该行?这显然不太理想,但如果在实际的foo.sh脚本中有一个不错的延迟,这应该可以解决。