bash - 从文件夹中选取文件、处理、删除
bash - Pick files from folder, process, delete
在 Linux shell 中,我想将文件夹视为一袋文件。有一些进程将文件放入这个包中。正好有一个进程处于以下两种状态之一:
- 处理文档,然后将其删除
- 等待文件夹中存在任意文档,然后处理它
文件的处理顺序或文件名称无关紧要。
从文件夹中获取文件的独特过程在 bash 中看起来像什么?处理意味着以文件名作为参数调用另一个程序。
请注意,在我手动终止之前,这个独特的过程不会终止。
最简单的方法可能是遍历文件,"calls" 处理程序并删除文件:
for f in /path/to/folder/*; do
program_that_processes_file $f
rm $f
done
虽然这有一个小问题:如果创建文件的程序不是自动执行的,您可以处理甚至删除尚未完全写入的文件。最简单的解决方案是让编写器写入一个临时目录,然后当文件全部完成后,将其移动到最终目标目录。
inotify-tools 是获取目录更改即时通知的理想工具。收到新文件创建通知后,您可以处理并删除它。
您可以使用 incrond
,它代表 "inotify cron daemon"。它是一个在后台运行并监视 table 中指定的目录的守护进程。
可以使用
创建有效的配置
incrontab -e
这将打开一个编辑器,您可以输入要观看的目录和操作,例如,
/path/to/observed/directory IN_CREATE,IN_MOVED_TO <command> $@/$#
<command>
是您要在其中一个事件 (IN_CREATE,IN_MOVED_TO
) 被触发时执行的命令或脚本。 $@/$#
是创建或移动到监视文件夹并将传递给 <command>
的文件的路径。这基本上就是您开始观看文件夹所需要做的全部工作。
您必须通过告诉哪些用户可以使用该服务来初始化 incrond 一次。您可以通过将用户添加到 incrond.allow
来允许用户使用 incrond,例如
echo 'root' >> /etc/incrond.allow
echo '<username>' >> /etc/incrond.allow
注意,root
也必须在 incrond.allow
中。
现在您可以通过简单地调用
来启动守护进程
incrond
有关 incrond
的更多信息:
这个怎么样:
while true; do
files=( $(ls) );
if [[ ${#files[@]} -eq 0 || (`lsof -c write_process -- ${files[0]}`)]]; then
sleep 5;
else
process ${files[0]};
rm ${files[0]};
fi;
done
...或者这个(可能不健康):
while true; do
files=( $(ls) );
if [ ${#files[@]} -ne 0 && ! (`lsof -c write_process -- ${files[0]}`)]; then
process ${files[0]};
rm ${files[0]};
fi;
done
如前所述,我必须确保文件已完全写入文件夹中。我通过检查写入文件的进程的 lsof 来做到这一点。但是,我还不确定如何将同一程序的多次执行作为一个进程来处理...
在 Linux shell 中,我想将文件夹视为一袋文件。有一些进程将文件放入这个包中。正好有一个进程处于以下两种状态之一:
- 处理文档,然后将其删除
- 等待文件夹中存在任意文档,然后处理它
文件的处理顺序或文件名称无关紧要。
从文件夹中获取文件的独特过程在 bash 中看起来像什么?处理意味着以文件名作为参数调用另一个程序。
请注意,在我手动终止之前,这个独特的过程不会终止。
最简单的方法可能是遍历文件,"calls" 处理程序并删除文件:
for f in /path/to/folder/*; do
program_that_processes_file $f
rm $f
done
虽然这有一个小问题:如果创建文件的程序不是自动执行的,您可以处理甚至删除尚未完全写入的文件。最简单的解决方案是让编写器写入一个临时目录,然后当文件全部完成后,将其移动到最终目标目录。
inotify-tools 是获取目录更改即时通知的理想工具。收到新文件创建通知后,您可以处理并删除它。
您可以使用 incrond
,它代表 "inotify cron daemon"。它是一个在后台运行并监视 table 中指定的目录的守护进程。
可以使用
incrontab -e
这将打开一个编辑器,您可以输入要观看的目录和操作,例如,
/path/to/observed/directory IN_CREATE,IN_MOVED_TO <command> $@/$#
<command>
是您要在其中一个事件 (IN_CREATE,IN_MOVED_TO
) 被触发时执行的命令或脚本。 $@/$#
是创建或移动到监视文件夹并将传递给 <command>
的文件的路径。这基本上就是您开始观看文件夹所需要做的全部工作。
您必须通过告诉哪些用户可以使用该服务来初始化 incrond 一次。您可以通过将用户添加到 incrond.allow
来允许用户使用 incrond,例如
echo 'root' >> /etc/incrond.allow
echo '<username>' >> /etc/incrond.allow
注意,root
也必须在 incrond.allow
中。
现在您可以通过简单地调用
incrond
有关 incrond
的更多信息:
这个怎么样:
while true; do
files=( $(ls) );
if [[ ${#files[@]} -eq 0 || (`lsof -c write_process -- ${files[0]}`)]]; then
sleep 5;
else
process ${files[0]};
rm ${files[0]};
fi;
done
...或者这个(可能不健康):
while true; do
files=( $(ls) );
if [ ${#files[@]} -ne 0 && ! (`lsof -c write_process -- ${files[0]}`)]; then
process ${files[0]};
rm ${files[0]};
fi;
done
如前所述,我必须确保文件已完全写入文件夹中。我通过检查写入文件的进程的 lsof 来做到这一点。但是,我还不确定如何将同一程序的多次执行作为一个进程来处理...