我有一个正在运行的文件生成器,其中每个文件的名称都按字母顺序排列在前一个文件之后。起初我像 一样进行循环for file in /path/to/files*; do...
,但我很快意识到 glob 只会在循环之前扩展,并且不会处理循环时创建的任何新文件。
我目前这样做的方式非常丑陋:
while :; do
doneFileCount=$(wc -l < /tmp/results.csv)
i=0
for file in *; do
if [[ $((doneFileCount>i)) = 1 ]]; then
i=$((i+1))
continue
else
process-file "$file" # prints single line to stdout
i=$((i+1))
fi
done | tee -a /tmp/results.csv
done
有没有任何简单的方法可以循环遍历不断增加的文件列表,而无需上述黑客攻击?
我认为通常的方法是让新文件出现在一个目录中,并在处理后重命名/将它们移动到另一个目录,这样它们就不会再次碰到同一个 glob。所以像这样
或者类似地更改文件扩展名:
在 Linux 上,您还可以使用
inotifywait
获取有关新文件的通知。在任何一种情况下,您都需要观察仍在写入的文件。就地创建的大文件不会以原子方式显示,但您的脚本可能会在它仅写入一半时开始处理它。
上面的 inotify
close_write
事件将在写入进程关闭时查看文件(但它也会捕获修改后的文件),而该create
事件将在文件首次创建时查看文件(但它可能仍会被写入)。moved_to
只是捕获移动到正在监视的目录中的文件。