我有一个文件夹 A,其中时不时会出现新文件。可能会出现一个小时没有新文件的情况,但也有可能每秒有几个新文件的情况。所有文件的名称中都有唯一的时间戳和不同的文件扩展名。无法修改将内容放入文件夹的内容、方式和时间。这是我电脑上的一个目录,可以通过 ftp 从外部访问。
在另一个文件夹中,一旦有新文件,BI 希望获得文件夹 A 中名为“Newest.jpg”的最新 jpg 文件的副本。延迟1秒就好了。它应该模仿网络摄像头的输出。
在运行 Ubuntu 14.04 LTS 的类 Raspberry 系统上实现此目的的最佳且计算成本最低的方法是什么?
答案1
如果安装该软件包,inotify-tools
您可以编写一个简单的脚本,该脚本将inotify
在创建新文件时获取事件。
inotifywait -m -e create --format %f A |
while read filename
do ln -f A/"$filename" B/Newest.jpg
done
每当在监视目录中创建新文件时A
,都会以给定格式打印事件%f
,即仅打印文件名。 shell 循环读取此内容并创建一个链接。文件创建和建立链接之间不应有任何延迟。
如果您需要从匹配中排除某些文件名,您可以--exclude
向 中添加正则表达式模式inotifywait
,例如--exclude '.*.wav$'
以排除*.wav
文件。或者,*.jpg
在 shell 循环内测试所需的模式可能会更简单。如果您使用的是 bash,您可以简单地在开头添加do
:
[[ "$filename" != *.jpg ]] && continue
这针对 glob 模式而不是正则表达式进行测试。
答案2
首先,创建一个符号链接任何文件放在目录中,并将其命名为“latest”:
ln -s somefile.jpg latest
然后根据需要在目录中运行以下命令:
find . -type f -newer latest -exec ln -fs {} latest \;
这实际上相当优雅,因为评估顺序并不重要。该命令的末尾 编辑:这是错误的。根据POSIX:latest
将是指向目录中最新文件的符号链接。
这-用户,-团体, 和-较新每个初选只能对各自的论点进行一次评估。
这实际上使这种方法无效,但您仍然可以从中做一些事情。然而,考虑到这一事实,我会inotify
按照其他答案中的建议使用。
我不知道它会消耗多少CPU周期,但只是运行:
while true; do find . -type f -name '*.jpg' -newer latest -exec ln -fs {} latest \; ; done
将确保latest
始终尽可能快地指向最新的 jpeg 文件。如果你不这样做预计如果每秒更新图像的频率超过一次,则可以使用 来while sleep 1
代替while true
。
请注意,随着目录中文件数量的增加,这将变得越来越低效。我对如何处理这个问题有一些想法,但由于它位于 ftp 上,因此它们可能不适用。
我的第一个想法是将旧文件作为同一find
命令的一部分移动到另一个目录中,这样就不必再次评估它们。问题是,latest
符号链接指向的文件被视为“较旧”,因为它不是较新的。我们不能动那文件,否则我们将破坏符号链接!
但是,由于我们只评估名为 .jpg 的文件,因此我们可以通过latest
创建硬链接而不是符号链接:
mkdir ../oldfiles
while sleep 1; do find . -type f -name '*.jpg' \( -newer latest -exec ln -f {} latest \; -o -exec mv {} ../oldfiles \; \)
同样,我不知道这将如何在 ftp 上进行,但对于本地文件来说它应该工作得很好。