1

将命令的 stdout 和 stderr 都记录到日志文件中相当简单:

./foo.sh &> log.txt

问题是在检查日志文件时,人们不再知道哪一行来自哪个流。这可以通过将 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
4

2 回答 2

2

也许您正在寻找script 它记录标准输出、标准错误和命令...它启动一个新的外壳,在其中记录所有内容(或使用-c _cmd_

 $ script tx1

你的color()函数破坏了顺序,因为sed正在缓冲......

于 2013-07-19T19:18:48.753 回答
1

如何将 stderr 重定向到 ./tmperr 并将 stdout 重定向到 ./tmpout,现在在后台运行两个脚本,每个脚本都从 tmperr 或 tmpout 连续读取一行,然后删除该行?这显然不太理想,但如果实际的 foo.sh 脚本有相当大的延迟,这应该可以解决。

于 2015-06-16T15:33:50.157 回答