RHEL 8.9(zsh)环境下tee -a串联指令无法追加写入文件问题
问题场景
在RHEL 8.9(zsh shell)环境下,两种命令写法产生了不同的日志追加结果:
- 写法1:可正常将三条命令的输出追加到日志文件,同时在终端显示输出
- 写法2:终端能正常显示三条输出,但日志文件仅保留最后一条命令的输出(前两条内容未写入或被覆盖)
写法1(正常工作)
date >> ./net.log | tee && ifconfig | awk 'NR == 4' >> ./net.log | tee && ifconfig | awk 'NR == 6' >> ./net.log | tee
写法2(未按预期追加)
date | tee -a ./net.log && ifconfig | awk 'NR == 4' | tee -a ./net.log && ifconfig | awk 'NR == 6' | tee -a ./net.log
可能的原因及排查方向
1. zsh别名或自定义函数覆盖了标准tee命令
如果你的zsh环境中存在tee的别名或自定义函数,可能改写了tee -a的行为。执行以下命令验证:
type tee
若输出不是tee is /usr/bin/tee,说明存在别名/自定义函数,可通过以下命令取消:
unalias tee # 取消别名 unfunction tee # 取消自定义函数
2. 标准tee命令异常(非GNU版本)
RHEL 8.9默认使用GNU tee,但如果系统中的tee被替换为其他版本(如busybox tee),可能存在-a选项兼容性问题。验证方法:
tee --version
正常输出应为tee (GNU coreutils) 8.32或类似版本。若不符,需恢复系统默认的tee命令。
3. 日志文件的特殊属性或权限问题
如果net.log设置了append-only属性(chattr +a)但被意外解除,或文件权限导致前两次写入失败,可检查:
lsattr ./net.log ls -l ./net.log
若lsattr输出含a,说明是追加属性,tee -a可正常写入;若文件权限对当前用户不可写,会导致写入失败。
4. 前两次tee命令实际未产生有效输出
虽然&&保证前一条命令成功才执行后一条,但如果ifconfig | awk 'NR == 4'或ifconfig | awk 'NR == 6'没有输出内容,会导致日志文件仅保留最后一条的有效输出。可单独验证:
date | tee -a ./test.log ifconfig | awk 'NR == 4' | tee -a ./test.log cat ./test.log
若test.log仅含date的输出,说明ifconfig的行号与预期不符,可通过以下命令查看实际行号对应内容:
ifconfig | nl
5. zsh缓冲区刷新延迟(概率极低)
多个串行tee命令写入同一文件时,可能存在缓冲区未及时刷新的情况,可强制刷新验证:
date | tee -a ./net.log; sync ifconfig | awk 'NR == 4' | tee -a ./net.log; sync ifconfig | awk 'NR == 6' | tee -a ./net.log; sync
总结
最常见的原因是tee命令被别名/自定义函数覆盖,或ifconfig输出的行号与预期不符导致前两次tee写入空内容。按上述步骤逐一排查即可定位问题。
内容的提问来源于stack exchange,提问作者Tarlak333

