![在 cron 中安排时,脚本中的 cat 多个文件会截断数据](https://linux22.com/image/99079/%E5%9C%A8%20cron%20%E4%B8%AD%E5%AE%89%E6%8E%92%E6%97%B6%EF%BC%8C%E8%84%9A%E6%9C%AC%E4%B8%AD%E7%9A%84%20cat%20%E5%A4%9A%E4%B8%AA%E6%96%87%E4%BB%B6%E4%BC%9A%E6%88%AA%E6%96%AD%E6%95%B0%E6%8D%AE.png)
我正在 OEL 6 上的 bash 脚本中整理多个文件。
for f in /share/scripts/stats/*.stat; do (cat "${f}"; echo) >> /share/scripts/stats/finalmail.html; done
当手动触发脚本时,它会完美地附加所有文件。但是,当脚本从 cron(每 5 分钟)运行一次时,有时(约 10% 的时间)仅附加 1-2 个文件中的部分数据。在调用此 cat 操作之前,我尝试列出每个文件的大小。最终文件大小有时不是所有文件大小的总和。
答案1
很有可能,您的脚本有时会在写入文件的同时触发。运行时cat
,它会复制当前存在的数据。它无法知道稍后会添加更多数据。
为了避免这种情况,假设要快速生成文件,最好的方法是更改生成数据的程序。不要直接写入最终名称,而是写入临时文件并在所有数据都存在时重命名临时文件,例如
gather_data --origin=somewhere >somewhere.stat.tmp &&
mv somewhere.stat.tmp somewhere.stat
如果您无法更改生成过程,那么您可以使用以下命令对正在关闭的文件做出反应inotify。根据这些文件的创建和删除方式,使用可能更有意义因克朗,例如您可以使用此 incrontab 行:
/share/scripts/stats IN_CLOSE_WRITE case $@/$# in *.stat) new_stat_file $@/$# esac
new_stat_file
将是包含新文件的脚本。不要只是运行类似的东西cat *.stat
,因为它也可能会获取部分文件。重命名文件或文件的副本,例如
/share/scripts/stats IN_CLOSE_WRITE case $@/$# in *.stat) ln $@/$# /share/scripts/stats/ready/; esac
然后从 中获取文件/share/scripts/stats/ready
而不是/share/scripts/stats
.