我一直在研究如何验证文件系统A上的数百万个文件是否已经被移动到文件系统B.在进行系统迁移时,很明显需要审计所有文件来证明文件已被移动。这些文件最初是通过rsync移动的,它确实提供了日志,但不是采用有助于进行审计的格式。所以,我写了这个脚本来索引系统A上的所有文件:
#!/bin/bash
# Get directories and file list to be used to verify proper file moves have worked successfully.
LOGDATE=`/usr/bin/date +%Y-%m-%d`
FILE_LIST_OUT=/mounts/A_files_$LOGDATE.txt
MOUNT_POINTS="/mounts/AA mounts/AB"
touch $FILE_LIST_OUT
echo TYPE,USER,GROUP,BYTES,OCTAL,OCTETS,FILE_NAME > $FILE_LIST_OUT
for directory in $MOUNT_POINTS; do
# format: type,user,group,bytes,octal,octets,file_name
gfind $directory -mount -printf "%y","%u","%g","%s","%m","%p\n" >> $FILE_LIST_OUT
done
文件索引工作正常,大约需要两个小时来索引〜3000万个文件。
在B方面是我们遇到问题的地方。我编写了一个非常简单的shell脚本来读取索引文件,测试文件是否存在,然后计算出有多少文件,但是在索引文件名上循环3000万行时,内存不足。通过while循环有效地执行下面的这一小段代码,并使用计数器增加找到但未找到的文件。
if [ -f "$TYPE" "$FILENAME" ] ; then
print file found
++
else
file not found
++
fi
我的问题是:
答案 0 :(得分:1)
你刚刚使用了rsync,再次使用它......
<强> - 忽略-现有强>
这告诉rsync跳过更新目标上已存在的文件(这不会忽略现有目录,或者什么都不会完成)。另请参见--existing。
此选项是传输规则,而不是排除,因此它不会影响进入文件列表的数据,因此不会影响删除。它只是限制了接收方请求传输的文件。
当需要继续执行被中断的备份运行时,此选项对于使用--link-dest选项进行备份的用户非常有用。由于--link-dest运行被复制到一个新的目录层次结构中(当它正确使用时),使用--ignore existing将确保已经处理的文件不会被调整(这避免了对权限的更改)硬链接文件)。这意味着此选项仅查看目标层次结构本身中的现有文件。
这实际上会解决任何问题(至少在同一意义上,文件存在的测试中的任何差异列表都可以解决问题。使用--ignore-existing
意味着rsync
只进行文件存在的测试(因此,它会根据您的请求构建差异列表并在内部使用它。如果您只想了解差异的信息,请检查--dry-run
和--itemize-changes
。
假设您有两个目录foo
和bar
。假设bar
有三个文件1
,2
和3
。假设bar
有一个目录quz
,其中有一个文件1
。目录foo
为空:
现在,结果是
$ rsync -ri --dry-run --ignore-existing ./bar/ ./foo/
>f+++++++++ 1
>f+++++++++ 2
>f+++++++++ 3
cd+++++++++ quz/
>f+++++++++ quz/1
请注意,您对 cd +++++++++非常感兴趣 - 这只是向您显示rsync
已发布chdir
。现在,让我们在名为foo
的{{1}}中添加一个文件,让我们使用1
删除grep
,
chdir
f 适用于档案。 ++++++++++++++++++++++
这是奖金,删除$ rsync -ri --dry-run --ignore-existing ./bar/ ./foo/ | grep -v '^cd'
>f+++++++++ 2
>f+++++++++ 3
>f+++++++++ quz/1
,然后它会继续为您做出更改。
答案 1 :(得分:0)
答案 2 :(得分:0)
在shell脚本中读取3000万行文件绝对没有问题。您的进程失败的原因很可能是您尝试将文件完全读入内存,例如做错了像for i in $(cat file)
。
读取文件的正确方法是:
while IFS= read -r line
do
echo "Something with $line"
done < someFile
shell脚本不合适,是的。您应该使用diff工具:
diff -rNq /original /new
答案 3 :(得分:0)
如果您不是特别关注该解决方案是一个脚本,您还可以查看meld,它可以让您轻松地对目录树进行区分,如果您有任何设置,也可以设置忽略模式。