我正在编写备份脚本,遇到了一个问题。我想把我的文档备份到ftp服务器上。因为我不喜欢encfs,所以我试图通过使用z-zip和加密档案来实现这一点。这运行得很好,但我只想在子目录中的文件发生更改时创建一个新的存档,所以lftp只上传更改后的文件。
我的代码片段如下:
cd /mnt/HD_a2/documents
for i in */
do 7za a -t7z /mnt/HD_a2/encrypted/ul_doc/"${i%/}.7z" -p1234 -mhe "$i"
done
当"I"中的文件在过去7天内发生更改时,我如何更改此代码,使其仅创建新的存档?(此脚本由cron每7天执行一次)
for i in */
do
if [ `find "$i" -type f -mtime -7 | wc -l` -gt 0 ]
then 7za a -t7z /mnt/HD_a2/encrypted/ul_doc/"${i%/}.7z" -p1234 -mhe "$i"
fi
done
因此,Barmar的答案几乎是正确的,但它没有正确计算文件数。我四处寻找了其他类似的问题,这似乎是一个常见的错误(请注意,这对他的解决方案并不重要,但如果其他程序员接触到它,可能会感到困惑,因为这不是大多数人所期望的),没有人考虑文件名可能包含换行符这一事实。因此,这里有一个更好的版本,可以为您提供正确的文件计数:
for i in */
do
fileCount=$(find "$i" -type f -mtime -8 -exec printf . ;)
if (( ${#fileCount} > 0 )); then
7za a -t7z /mnt/HD_a2/encrypted/ul_doc/"${i%/}.7z" -p1234 -mhe "$i"
fi
done
但是如果你有成千上万的文件呢?这将构建一个与文件数量完全一样长的字符串。
所以我们可以使用这个:
for i in */
do
fileCount=$(find "$i" -type f -mtime -8 -exec printf . ; | wc -c)
if (( fileCount > 0 )); then
7za a -t7z /mnt/HD_a2/encrypted/ul_doc/"${i%/}.7z" -p1234 -mhe "$i"
fi
done
或者这个:
for i in */
do
fileCount=$(find "$i" -type f -mtime -8 -exec echo ; | wc -l)
if (( fileCount > 0 )); then
7za a -t7z /mnt/HD_a2/encrypted/ul_doc/"${i%/}.7z" -p1234 -mhe "$i"
fi
done
希望无用的字符串数据不会被缓存。
但我们只需要知道是否至少有一个文件,我们不必计算所有文件这样,如果发现什么东西,我们可以立即停止。
for i in */
do
fileFound=$(find "$i" -type f -mtime -8 | head -n 1)
if [[ $fileFound ]]; then
7za a -t7z /mnt/HD_a2/encrypted/ul_doc/"${i%/}.7z" -p1234 -mhe "$i"
fi
done
就是这样。这个解决方案将工作得更快,因为它不必查找其他文件,甚至不必检查它们的mtime
。尝试在没有head
的情况下运行此代码,您会注意到一个显著的差异——对于我的主文件夹,从几个小时到不到一秒钟。(我甚至不确定它是否能在我的电脑上完成,我的主文件夹中有数百万个小文件…)