shell脚本使用cat命令记录输出报错input file is output file如何解决
问题根源
shell执行带重定向的命令时,会先处理重定向逻辑,再执行重定向符号左边的命令,你的命令执行顺序实际如下:
- shell先执行
>> Run.log操作:如果Run.log不存在则创建该文件,若存在则更新该文件的修改时间 - 再执行
cat "$(ls -rt | tail -n1)":此时Run.log是当前目录下修改时间最新的文件,ls -rt | tail -n1返回的结果就是Run.log - 相当于你执行了
cat Run.log >> Run.log,cat检测到输入文件和输出重定向目标是同一个文件,为了避免无限读取写入的死循环就抛出了对应报错。
你在终端直接执行没问题的原因是:终端执行时当前目录已经存在其他修改时间比Run.log新的文件,ls -rt返回的结果不是Run.log,所以不会触发报错。
修复方案
- 方案1:先获取最新文件名,再执行带重定向的写入操作,保证获取文件名时
Run.log的修改时间还没被更新
# 先获取最新文件名,此时还没执行重定向,Run.log不会被选中 latest_file=$(ls -rt | tail -n1) # 再执行写入操作 cat "$latest_file" >> Run.log
- 方案2:将日志文件
Run.log放到当前目录以外的路径,比如./logs/Run.log,避免日志文件出现在ls的扫描结果中 - 方案3:获取最新文件时过滤掉
Run.log,避免它被选中
latest_file=$(ls -rt | grep -v '^Run.log$' | tail -n1) cat "$latest_file" >> Run.log
注意:
ls -rt获取最新文件的写法本身存在兼容性问题,如果文件名包含空格、换行符等特殊字符时会出现异常,生产环境建议用find命令替代实现同类需求。
内容的提问来源于stack exchange,提问作者INDRAJIT GHOSH
相关产品推荐
相关产品推荐

