有没有办法判断文件是否已复制完成?

有没有办法判断文件是否已复制完成?

场景是这样的:机器 A 中有文件我想复制到机器 C。机器 A 不能直接访问 C,但可以访问可以访问机器 C 的机器 B。我使用 scp 从机器 A 复制到 B,然后从 B 复制到 C。

机器B的存储空间有限,所以当文件进来时,我需要将它们复制到C并从B中删除。第二次复制的速度要快得多,所以这对带宽来说没有问题。

我可以手动完成,但我很懒。我想在 B 或 C 上运行一个脚本,将每个文件复制到 C每个人结束时. scp 作业正在从 A 运行。

因此我需要一种方法来询问(最好使用 bash 脚本)文件 X.avi 是否“完成”复制。每个文件的大小都不同,我无法真正预测完成的大小或时间。

编辑:顺便说一下,如果时间尺度很重要的话,文件传输时间从 A 到 B 大约需要 1 小时,从 B 到 C 大约需要 10 分钟。

答案1

常见的做法是先将其复制到一个临时文件名中,最好是隐藏文件。复制完成后,执行复制的脚本会将其重命名为非隐藏文件名。

然后机器 B 上的脚本就可以监视非隐藏文件。

机器 A 上的脚本如下所示:

for file in `ls *` ; do
    scp $file user@host:~/.${file}.tmp
    ssh user@host "mv ~/.${file}.tmp $file"
done

虽然这不能满足OP使用单行的愿望

scp * user@host:~/

它完成了相同的事情,并且还允许机器 B 在完成时传输每个文件而无需等待下一个文件。

答案2

机器 B 上是否lsof显示 scp 已打开文件?如果是,您可以观察lsof并查看 scp 何时关闭文件。如果没有,您可以观察文件的大小,并在给定时间段(例如 5 分钟)内文件未发生变化后,将其从 B 复制到 C。

第三个选择是将文件从 A 复制到 C 上的“in_progress”目录。在 A 上复制完成后,执行mv命令移出“in_progress”目录。

答案3

我刚刚想到了另一个完全不相关的选项。根本不使用 scp。如果这可行,请告诉我:

  1. 在 B 上的某处创建一个 fifo 管道:mkfifo /tmp/xfer

  2. 在 A 上,不要使用 scp,而是tar -cz files | ssh B 'cat > /tmp/xfer

  3. 在 C 上,运行ssh B 'cat /tmp/xfer' | tar -xz

这样,数据就不会存储在 B 上,而只会通过管道传输。缺点是,您一次只能复制一份……

您需要确保 C 上的进程每次完成时都会重新启动。

答案4

不需要 mkfifo。在机器 B 上运行以下命令:

ssh A 'tar -cz files' | ssh C 'tar -xz'

您可能会发现 tar 的 -C 选项很有用。

如果需要在机器 A 上启动复制,只需执行以下操作:

tar -cz files' | ssh B "ssh C 'tar -xz'"

但要注意正确的引用。

相关内容