![在控制台上输出 stderr 和 stdout 并同时将它们存储在文件中](https://linux22.com/image/35833/%E5%9C%A8%E6%8E%A7%E5%88%B6%E5%8F%B0%E4%B8%8A%E8%BE%93%E5%87%BA%20stderr%20%E5%92%8C%20stdout%20%E5%B9%B6%E5%90%8C%E6%97%B6%E5%B0%86%E5%AE%83%E4%BB%AC%E5%AD%98%E5%82%A8%E5%9C%A8%E6%96%87%E4%BB%B6%E4%B8%AD.png)
我可以在控制台屏幕上输出stdout
和stderr
并将其中之一存储到日志文件中吗?
我写了一个测试shell脚本:
#!/bin/sh
echo OUT! >&1
echo ERR! >&2
我只需运行脚本就可以将它们输出到屏幕上:
$./test
OUT!
ERR!
我可以通过以下方式输出stderr
并捕获stdout
到日志文件中:
$./test | tee 1>log
ERR!
$cat log
OUT!
我什么都不能输出,只能通过以下方式捕获所有内容stdout
并stderro
写入日志文件:
$./test 2>&1| tee 1>log
$cat log
OUT!
ERR!
我可以通过以下方式输出stdout
和stderr
并将它们全部捕获到日志文件中:
$./test 2>&1 | tee log
OUT!
ERR!
$cat log
OUT!
ERR!
我可以通过以下方式将 can catch 输出stdout
到日志文件中:
$./test | tee 2>&1 log
ERR!
OUT!
$cat log
OUT!
我的问题是:
-
如何输出
stdout
并捕获stderr
到文件中?(我尝试过./test|tee 2>log
,但不起作用) -
如何将两者都输出并捕获
stderr
到文件中?
答案1
- 如何仅输出 stdout 并将 stderr 捕获到文件中?(我尝试了 ./test|tee 2>log,但不起作用)
$ ./test 2>log
OUT!
$ cat log
ERR!
- 如何仅输出两者并将 stderr 捕获到文件中?
$ ./test 2>&1 >/dev/tty | tee log
OUT!
ERR!
$ cat log
ERR!
如果此表达式是较大管道的一部分,那么您可能希望避免使用/dev/tty
.一种方法是交换 stdout 和 stderr。要进行此交换,我们需要创建第三个文件句柄,如下所示:
$ exec 3>&1; ./test 2>&1 1>&3 | tee log; exec 3>&-
OUT!
ERR!
$ cat log
ERR!
第一条语句 ,exec 3>&1
将文件句柄 3 分配给当前的标准输出(无论是什么)。然后,./test 2>&1 1>&3 | tee log
将 stderr 通过管道传输到tee
命令,同时将 stdout 发送到文件句柄 3。最后,为了良好的管理,exec 3>&-
关闭文件句柄 3。
附加说明和评论
关于:
我可以通过以下方式输出 stderr 并将 stdout 捕获到日志文件中:
$./test | tee 1>log ERR! $cat log OUT!
可以简化为:
$ ./test >log
ERR!
$ cat log
OUT!
另外,关于:
我什么都不能输出,只能通过以下方式将所有 stdout 和 stderro 捕获到日志文件中:
$ ./test 2>&1| tee 1>log $ cat log OUT! ERR!
可以简化为:
$ ./test >log 2>&1
$ cat log
OUT!
ERR!
或者,使用bash
,但不使用 POSIX shell,可以使用更简单的形式:
$ ./test &>log
$ cat log
OUT!
ERR!
答案2
shell 重定向应该足够了。首先,重定向stderr
到文件...
$ ./test 2> myfile.txt
这里stdout
仍然是屏幕,因为它没有被重定向。myfile.txt
将包含 ERR。
然后,如果您想输出两者,并且仍然捕获stderr
到文件中,您可能需要分两步进行一些命令替换......
$ ./test 2> >(tee myfile.txt >&2)
这会将错误流发送到tee
进程,该进程将重新打印它们。stdout
保持不变。有关更多信息,请查看此 Stack Overflow 问题。
同样,如果您想捕获stdout
文件并保持stderr
不变......
$ ./test > >(tee myfile.txt)
答案3
好吧,伙计们和女孩们……
只是为了丰富这个线程,我认为最好用一般简化的情况发布答案。
将 stdout 和 stderr 输出到终端并将 stdout 和 stderr 捕获到文件中...
测试 stdout 和 stderr 是否输出到终端和文件...
rm -f test.log
ping 127.0.0.1 -c 6 2>&1 | tee test.log
cat test.log
确认 stderr 是否输出到终端和文件...
rm -f test.log
ping e.r.r.or -c 6 2>&1 | tee test.log
cat test.log
谢谢! =D
[参考号:https://stackoverflow.com/a/12928057/3223785]