为了测试目的,我想分别保存stdout和stderr,以供后续代码检查。例如,带有错误输入的测试运行应该导致输出到stderr,但是stdout上没有任何结果,而具有正确输入的测试运行应该导致输出到stdout,但是没有输出到stderr。保存必须是同步的,以避免使用测试的竞争条件(因此我不能使用过程替代)。
为了能够在事后调试测试,我还需要在输出的序列中看到stdout和stderr。因此,我要么将它们保存到相同的文件/变量/任何东西中,要么将它们分别保存到终端。
为了测试发生了哪些错误,我还需要命令的退出代码。
由于效率和准确性的原因,我当然不能每次测试两次。
例如,是否可以在同一个命令中将stdout重定向到stdout.log,stderr重定向到stderr.log,并将两者重定向到output.log?还是对stdout和stderr分别使用同步 tee命令?还是保存stdout和stderr的副本以分离变量?
Update:看起来tim的解决方案几乎可以工作(修改为在终端上输出,而不是登录到all.log):
$ set -o pipefail
$ {
{
echo foo | tee stdout.log 2>&3 3>&-
} 2>&1 >&4 4>&- | tee stderr.log 2>&3 3>&-
} 3>&2 4>&1
foo
$ cat stdout.log
foo
$ cat stderr.log
$ {
{
echo foo >&2 | tee stdout.log 2>&3 3>&-
} 2>&1 >&4 4>&- | tee stderr.log 2>&3 3>&-
} 3>&2 4>&1
foo
$ cat stdout.log
$ cat stderr.log
foo
$ bar=$({
{
echo foo | tee stdout.log 2>&3 3>&-
} 2>&1 >&4 4>&- | tee stderr.log 2>&3 3>&-
} 3>&2 4>&1)
$ echo "$bar"
foo
$ cat stdout.log
foo
$ cat stderr.log
$ bar=$({
{
echo foo >&2 | tee stdout.log 2>&3 3>&-
} 2>&1 >&4 4>&- | tee stderr.log 2>&3 3>&-
} 3>&2 4>&1)
$ cat stdout.log
$ cat stderr.log
foo
$ echo "$bar"
foo除了上一次迭代,bar的值被设置为stderr的内容,这似乎是可行的。对所有这些都有什么建议吗?
发布于 2010-12-21 10:48:37
请看BashFAQ/106。吃你的蛋糕也不容易。
从这一页:
但有些人既不接受stdout和stderr之间的分离,也不接受线的去同步化。他们是纯粹主义者,所以他们要求最困难的形式--我想把stdout和stderr一起记录到一个文件中,但我也希望他们能维护他们原来的、独立的目的地。 为了做到这一点,我们首先要做几点笔记:
所以:
# Bash
> mylog
exec > >(tee -a mylog) 2> >(tee -a mylog >&2)
echo A >&2
cat file
echo B >&2这确保日志文件是正确的。它不能保证编写者在下一个shell提示符之前完成:
~$ ./foo
A
hi mom
B
~$ cat mylog
A
hi mom
B
~$ ./foo
A
hi mom
~$ B另外,请参见BashFAQ/002和BashFAQ/047。
发布于 2010-12-21 12:03:02
这听起来像是多人的任务。
要在不使用进程替换的情况下测试同步输出或磁盘写入,您可能需要使用Bash重定向技巧和tee(1),类似于以下内容:
echos() { echo "hello on stdout"; echo "hello on stderr" 1>&2; return 0; }
{
{
echos 3>&- |
tee stdout.log 2>&3 3>&-
} 2>&1 >&4 4>&- |
tee stderr.log 2>&3 3>&-
} 3>&2 4>&1 2>&1 | tee /dev/stderr > all.log
open -e stdout.log stderr.log all.log # Mac OS X有关更多信息,请参见:http://codesnippets.joyent.com/posts/show/8769
要获取该命令的退出代码,您可能希望分别签出pipefail或PIPESTATUS (除了最后一个退出代码变量"$?"):
help set | grep -i pipefail
man bash | less -p pipefail
man bash | less -p PIPESTATUS发布于 2011-05-11 18:11:52
对于最后一次迭代,其中bar的值设置为stderr的内容,请尝试:
# restore original stdout & stderr at the end by adding: 1>&2 2>&1
bar="$(
{
{
echo foo >&2 | tee stdout.log 2>&3 3>&-
} 2>&1 >&4 4>&- | tee stderr.log 2>&3 3>&-
} 3>&2 4>&1 1>&2 2>&1
)"
echo "$bar"https://stackoverflow.com/questions/4497817
复制相似问题