我知道如何使用tee写入aaa.shbbb.out的输出(standard output),同时仍在终端中显示:

./aaa.sh | tee bbb.out

我现在如何将standard error写入名为ccc.out的文件,同时仍显示它?

推荐答案

我想你还是想在终端上看到STDERR和STDOUT.你可以 Select Josh Kelley的答案,但我发现在后台保留一个tail,这样会输出你的日志(log)文件,非常粗糙和笨拙.请注意,你需要如何保存exra FD,并在事后通过杀死它来进行清理,从技术上讲,应该在trap '...' EXIT中这样做.

有一种更好的方法,你已经发现了:tee.

只是,不要只在stdout上使用它,而是为stdout和stderr分别准备一个T恤.你将如何做到这一点?进程替换和文件重定向:

command > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)

让我们分开来解释一下:

> >(..)

>(...)(进程替换)创建一个FIFO,让tee监听.然后,它使用>(文件重定向)将command的标准输出重定向到第一个tee正在监听的FIFO.

第二点也是一样:

2> >(tee -a stderr.log >&2)

我们再次使用进程替换来生成一个tee进程,该进程从STDIN读取数据并将其转储到stderr.log中.tee将其输入输出回STDOUT,但由于它的输入是我们的STDERR,所以我们想再次将tee的STDOUT重定向到我们的STDERR.然后我们使用文件重定向将command的STDERR重定向到FIFO的输入(tee的STDIN).

http://mywiki.wooledge.org/BashGuide/InputAndOutput

进程替换是一件非常可爱的事情,你可以 Select bash作为shell,而不是sh(POSIX或Bourne).


sh年中,你必须手动操作:

out="${TMPDIR:-/tmp}/out.$$" err="${TMPDIR:-/tmp}/err.$$"
mkfifo "$out" "$err"
trap 'rm "$out" "$err"' EXIT
tee -a stdout.log < "$out" &
tee -a stderr.log < "$err" >&2 &
command >"$out" 2>"$err"

Linux相关问答推荐

通过ssh传输参数时避免字符串拆分

仅使用Find搜索32字符长的目录

使用 PowerShell 删除重复行所需的时间比 WSL 长得多

如何在 Linux 上打印带有屏蔽值的环境名称?

从另一个文件中的大文件中查找行的最快方法

Rust unix 进程

我需要制作一个 awk 脚本来解析文件中的文本.我不确定我是否做得正确

为什么要命令; ls -l file_doesnot_exists > /dev/null 2>&1 正在工作; ls -l 2>&1 file_doesnot_exists > /dev/null 不是

使用 bash 中的数字对 RPM 内核字符串进行版本排序返回不正确的结果

在 puppet 中管理 linux 的用户密码

如何在不包括可用空间的情况下创建光盘(sd 卡)的 .IMG 映像?

yum 可以告诉我哪些存储库提供了特定的包吗?

如何列出附加到Linux中共享内存段的进程?

*nix 系统上是否有与 COM 等效的功能?如果不是,那么 *nix 的可重用性方法是什么?

为什么两次使用 grep 时没有显示输出?

在 Linux 上忽略 glob() 中的大小写

在 PHP / Apache / Linux 环境中,为什么 chmod 777 是危险的?

如何从 shell 确定当前的 CPU 利用率?

在 Unix 上计算每行/字段的字符出现次数

未找到版本CXXABI_1.3.8(...要求)