如何正确重定向apt的STDERR到日志函数避免重复前缀?
解决APT输出分流与日志前缀重复问题
问题分析
你当前的代码将APT的STDOUT通过管道传入while循环处理,同时将STDERR重定向到log_trace()函数。但由于log_trace()(通过__logger_core)会将处理后的内容输出到终端(STDOUT),这部分输出又会被管道传入while循环再次处理,导致每条错误信息被两次添加» (APT)前缀,出现重复。
同时,原代码未将APT的进度信息(STDOUT)直接输出到终端,只能通过log_trace()的终端输出来显示,逻辑上存在冗余。
解决方案
核心思路是:让处理STDERR的log_trace()输出不进入管道(避免被while循环重复处理),同时确保APT的STDOUT进度信息能正常显示在终端并写入日志。
修改后的代码如下:
bool_update_required=0 apt update 2> >(log_trace "(APT)" >/dev/null) | while IFS= read -r line; do # 直接将进度信息输出到终端 printf "%s\n" "$line" if [[ $line != "All packages are up to date." ]]; then bool_update_required=1 fi # 将进度信息写入日志 log_trace "(APT)" <<<"$line" done
代码说明
- STDERR处理:
2> >(log_trace "(APT)" >/dev/null)将APT的STDERR传入log_trace(),同时将log_trace()的终端输出重定向到/dev/null,这样STDERR内容仅写入日志文件,不会显示在终端,也不会进入管道被while循环重复处理。 - STDOUT处理:
while IFS= read -r line读取APT的原始STDOUT进度信息,先通过printf输出到终端,再调用log_trace()写入日志,既满足进度显示需求,又保证日志记录完整。 - 格式保留:添加
IFS=确保读取包含前导空格的行时不会丢失原有格式。
效果验证
修改后,终端只会显示APT的进度报告(带» (APT)前缀),STDERR的警告/错误信息仅会出现在日志文件中,不会在终端显示,且不会出现前缀重复的问题,完全符合你期望的输出效果。
内容的提问来源于stack exchange,提问作者Rustam Alhas
相关产品推荐
相关产品推荐

