我有一个通过 FTP 上传文件的客户,我编写了一个脚本,主要用来监控 ftp 文件夹并将文件移动到生产机器上。如何在启动命令之前检查文件是否已通过 ftp 从客户处完全传输,scp
以避免传输部分文件?
答案1
答案2
如果没有客户的帮助,您将无法从 bash 正确地完成此操作。
在 FTP 服务器端,一些 FTP 服务器具有在上传终止后运行程序的方法(上传可能已经完成或者客户端可能已经断开连接,FTP 服务器无法知道上传是否真的完成)。
为了正确执行此操作,最好的解决方案是让客户端使用临时名称上传文件,然后在完成后将文件重命名为正确的名称。然后,您将所有名为“whatever.tmp”的文件排除在处理之外。否则,让客户端上传零字节锁定文件,上传真实文件,然后删除锁定文件。然后,您可以检查锁定文件是否存在
filelist = ...
if [ -e /home/ftp/incoming/lockfile ]; then exit; fi
... process $filelist ...
如果客户端上传了大量文件,那么每次运行脚本时锁文件可能都在那里,什么都做不了。在这种情况下,您必须根据锁文件检查文件的时间戳。比锁文件更早的文件应该是完整的:
for f in ...; do
if [ ! -e /home/ftp/incoming/lockfile -o $f -ot /home/ftp/incoming/lockfile ]; then
... process $f
fi
done
如果你的 FTP 服务器和客户端都不愿意参与,你可以这样做
- 创建文件和文件大小的列表。
- 将此列表与之前的文件列表进行比较
- 处理当前列表中与前一个列表中的文件相同的文件
- 保存当前文件列表覆盖前一个列表
- 等待 5 分钟然后返回 1。
5 分钟内文件没有变大可能就处理完了。这bash
留给读者练习。
答案3
我使用的解决方案(虽然不是万无一失的,但到目前为止对我来说 100% 有效)是每 10 秒查询一次文件大小,如果自上次查询以来文件大小没有发生变化,则假定它已完成并开始传输。
当然,网络可能会出现超过 10 秒的故障,导致无法完成所有内容的传输,但这种情况非常罕见,这就是 MD5 等校验和的用途。