如何将不含指定文本的行重定向到日志文件?现有语法为何无输出?
问题分析与解决方案
原命令错误原因
- 进程替换语法误用:
>(grep -v Dropping)是bash进程替换特性,你未在前面加>将程序输出重定向到该进程目标,反而将其作为myprogram的普通参数传入,完全无法实现过滤逻辑。 - 重定向顺序逻辑错误:后续的
> myprogram.log 2>&1直接把标准输出、标准错误全部写入日志文件,没有经过grep处理,所有含Dropping的行都会直接进入日志。 - 缓冲机制导致假死:即使管道逻辑写对,grep默认对非终端输出采用块缓冲,会攒够一定大小的内容才会向下游写入,短时间输出量小的时候会看起来像停止输出。
正确实现方案
推荐使用管道合并所有输出后过滤,同时开启grep行缓冲保证实时写入:
myprogram 2>&1 | grep --line-buffered -v "Dropping" > myprogram.log &
各部分逻辑说明:
2>&1:将标准错误(文件描述符2)重定向到标准输出(文件描述符1),确保所有输出都进入管道处理|:将合并后的所有输出传递给grep处理--line-buffered:强制grep按行缓冲输出,每行处理完成就向下游写入,不会出现攒内容的假死情况-v "Dropping":过滤掉所有包含Dropping关键字的行> myprogram.log:将过滤后的干净内容写入日志文件- 末尾
&:保持程序后台运行,符合原使用习惯
如果使用bash 4.0及以上版本,可以用更简洁的合并管道语法:
myprogram |& grep --line-buffered -v "Dropping" > myprogram.log &
其中|&是2>&1 |的简写,功能完全一致。
如果你确实需要使用进程替换写法,正确格式如下:
myprogram > >(grep --line-buffered -v "Dropping" > myprogram.log) 2>&1 &
注意进程替换前必须加额外的>,代表将标准输出重定向到进程替换的输入。
内容的提问来源于stack exchange,提问作者jacknad
相关产品推荐
相关产品推荐

