【问题标题】:Redirection using tee and sed使用 tee 和 sed 进行重定向
【发布时间】:2018-12-22 06:41:12
【问题描述】:

我在这里做错了什么?我没有从tee 得到任何STDOUT,但test.log 已正确填充。

perl test.pl | tee -i | sed 's/\x1b\[[0-9;]*m//g' > test.log

我的目标是将test.pl 打印的所有内容发送到STDOUT,并将相同的过滤版本(使用sed)转储到test.log

【问题讨论】:

标签: linux sed csh tee


【解决方案1】:

澄清后:

Daniel Schelper 的解决方案是正常人类可用 shell 的正确解决方案(谷歌为什么从不使用 csh)。不幸的是,有时我们别无选择,所以一个解决方案:

perl test.pl | tee /dev/stderr | sed 's/\x1b\[[0-9;]*m//g' > test.log

这样做是将stdout 复制到stderr,并且仅通过管道将stdout 转发。 perl 的输出将显示在屏幕上(通过stderr)。这有一个明显的警告,即任何真正的错误都可能被隐藏。更安全的解决方案可能是:

perl test.pl > /tmp/temp.log; cat /tmp/tmp.log & sed 's/\x1b\[[0-9;]*m//g' /tmp/tmp.log

这当然会产生一个额外的文件。与 Bourne shell 相比,csh 上的好选项通常涉及更多的中间文件。


旧答案

tee 应该始终是最后一个管道程序(除非你想在中途记录一些东西),并且有一个文件名作为参数。前者是因为重点是在屏幕上看到输出(而不是传递它),第二个是因为 tee 通常在不将输出发送到文件时也没有用。

就目前而言,您正在通过teestdout 传递到下一个管道sed,即使用> 运算符将所有内容转储到test.log。事实上,你不应该同时拥有>tee

perl test.pl | sed 's/\x1b\[[0-9;]*m//g' | tee test.log

在屏幕和日志中获取sed 的结果。如果我误解了,而您实际上确实想使用 tee 中途记录结果

perl test.pl | tee mid.log | sed 's/\x1b\[[0-9;]*m//g' > test.log

【讨论】:

  • 我的目标是将test.pl 打印的所有内容发送到STDOUT,并将过滤后的版本转储到test.log。那我该怎么做呢?
  • @DanielSchepler 刚回来 - 你想把它写成你自己的答案吗?
【解决方案2】:

这可能对你有用:

perl test.pl | tee -i /dev/stderr | sed -f sed.sed > test.log

perl 程序会将其输出泵送到标准输出。 T 恤将采用标准输出并将其作为标准输入接受并将其泵出到标准错误和标准输出。 sed 程序将接受标准输出并将其作为标准输入并将其泵出标准输出,标准输出将其重定向到test.log。标准错误将被定向到终端。

注意这可能会导致不必要的副作用。

【讨论】:

  • 我在 13 小时后来,和你同时发帖,太疯狂了。
【解决方案3】:

如果您使用的是 Bash,即脚本的 Posix 合规性并不重要,那么您可以使用 process substitution

perl test.pl | tee >(sed 's/\x1b\[[0-9;]*m//g' > test.log)

【讨论】:

  • 我使用tcsh,当我执行命令时它显示Missing name for redirect.
最近更新 更多