我有大量文本进入stdout
和stderr
;我想将所有内容记录在一个文件中(以相同的顺序(,并仅打印来自控制台中stdout
的内容以进行进一步处理(如grep
(。
> file
或&> file
的任何组合,即使使用|
或|&
也会永久重定向流,之后我无法通过管道传输它:
my_command > output.log | grep something # logs only stdout, prints only stderr
my_command &> output.log | grep something # logs everything in correct order, prints nothing
my_command > output.log |& grep something # logs everything in correct order, prints nothing
my_command &> output.log |& grep something # logs everything in correct order, prints nothing
任何使用tee
- 打印来自
stderr
的内容,然后记录来自stdout
的所有内容并将其打印出来,所以我失去了传入文本的顺序 - 如果我使用
|& tee
,则以正确的顺序记录两者,但是由于现在一切都在stdout
中,因此我失去了对流的控制。
例:
my_command | tee output.log | grep something # logs only stdout, prints all of stderr then all of stdout
my_command |& tee output.log | grep something # logs everything, prints everything to stdout
my_command | tee output.log 3>&1 1>&2 2>&3 | tee -a output.log | grep something # logs only stdout, prints all of stderr then all of stdout
现在我都没主意了。
这是我的测试用例的样子:
testFunction() {
echo "output";
1>&2 echo "error";
echo "output-2";
1>&2 echo "error-2";
echo "output-3";
1>&2 echo "error-3";
}
我希望我的控制台输出如下所示:
output
output-2
output-3
我的输出.log文件看起来像:
output
error
output-2
error-2
output-3
error-3
有关更多详细信息,我正在使用grep
过滤mvn clean install
的输出,以仅在终端中保留最少的信息,但我也希望在某个地方有一个完整的日志,以防我需要调查堆栈跟踪或其他东西。java 测试日志将发送到stderr
因此我选择在控制台输出中丢弃它。
虽然不是真正使用重定向或任何顺序的解决方案,但您可能希望为此使用annotate-output
。
假设script.sh
包含您的函数,那么您可以执行以下操作:
$ annotate-output ./script.sh
13:17:15 I: Started ./script.sh
13:17:15 O: output
13:17:15 E: error
13:17:15 E: error-2
13:17:15 O: output-2
13:17:15 E: error-3
13:17:15 O: output-3
13:17:15 I: Finished with exitcode 0
因此,现在可以轻松重新处理该信息并将其发送到所需的文件:
$ annotate-output ./script.sh
| awk '{s=substr($0,13)}/ [OE]: /{print s> "logfile"}/ O: /{print s}'
output
output-2
output-3
$ cat logfile
output
error
error-2
output-2
error-3
output-3
或任何其他tee
sed
cut
组合...
根据@CharlesDuffy的评论:
由于 stdout 和 stderr是并行处理的,因此可能会发生某些行在 stdout 将显示在稍后打印的 stderr 行之前(反之亦然(。
不幸的是,使用当前的注释策略很难解决此问题。 修复将 涉及切换到 PTRACE'ing 流程。 给尼斯一个(远(更高的优先级 但是,执行的程序可能会导致此行为出现的频率降低。
来源:
man annotate-output