lftp 实用程序有一个mirror
命令可将本地目录与远程服务器上的目录同步。该命令如何决定需要传输哪些文件?
特别是,如果一个文件已经存在于本地和远程目录中,那么它如何决定是否应该覆盖目标目录中的文件?它只是基于修改时间还是使用更复杂的启发式?
答案1
lftp 确实不是比较文件时执行文件内容完整性检查(例如哈希)。确保下载文件的完整性时了解这一点非常重要。
我首先怀疑这一点是在处理损坏的下载时,并注意到mirror
命令完成得太快而无法完成哈希。然后我通过检查lftp源代码进行确认。具体来说:FileInfo::SameAs
方法处理这个(github上最新的src(粘贴在下面))。
bool FileInfo::SameAs(const FileInfo *fi,int ignore) const
{
if(defined&NAME && fi->defined&NAME)
if(strcmp(name,fi->name))
return false;
if(defined&TYPE && fi->defined&TYPE)
if(filetype!=fi->filetype)
return false;
if((defined&TYPE && filetype==DIRECTORY)
|| (fi->defined&TYPE && fi->filetype==DIRECTORY))
return false; // can't guarantee directory is the same (recursively)
if(defined&SYMLINK_DEF && fi->defined&SYMLINK_DEF)
return (strcmp(symlink,fi->symlink)==0);
if(defined&DATE && fi->defined&DATE && !(ignore&DATE))
{
time_t p=date.ts_prec;
if(p<fi->date.ts_prec)
p=fi->date.ts_prec;
if(!(ignore&IGNORE_DATE_IF_OLDER && date<fi->date)
&& labs(date-fi->date)>p)
return false;
}
if(defined&SIZE && fi->defined&SIZE && !(ignore&SIZE))
{
if(!(ignore&IGNORE_SIZE_IF_OLDER && defined&DATE && fi->defined&DATE
&& date<fi->date)
&& (size!=fi->size))
return false;
}
return true;
}
仔细看一下你可以看到lftp尝试检查以下内容:
- 文件名
- 文件类型
- 是否有符号链接
- 日期
- 文件大小
即使这些检查也不能完全信任,因为如果某些内容返回为未定义,它们就会被简单地跳过。
如果幸运的话,FTP 主机将提供带有校验和哈希值的文本文件,以便您可以验证下载的内容。我就没那么幸运了,不得不完全重新下载。
答案2
最有可能的是,它正在检查文件大小和/或创建时间以查明文件是否被修改,除非您指定要复制哪些文件。
一小部分LFTP手册:
--ignore-time ignore time when deciding whether to download
--ignore-size ignore size when deciding whether to download
--only-missing download only missing files
--only-existing download only files already existing at target
-n, --only-newer download only newer files (-c won't work)
--upload-older upload even files older than the target ones
--transfer-all transfer all files, even seemingly the same at the
target site