用 cp 命令长时间复制海量文件,有无办法在中途间隔性地休息?

假如有两块 10TB 甚至更高容量的大硬盘,其中一块装满了数据,另外一块是空盘。要将前者的全部文件复制到后者,那么耗时会非常漫长,完全可能超过一整天。硬盘长时间高速运转会严重发热,特别是在炎热的夏季,可能导致硬盘损毁。

如果用 cp 命令来复制文件,有无办法让它每运行一个小时休息十分钟?在不修改 cp 自身源代码的情况下,能否用第三方工具来辅助实现?似乎很难用外部工具完成,好像只能修改 cp 的源代码。

在终端 cp 的话,Ctrl-Z 就休息了,fg 叫回来继续。

1赞

用 Ctrl+Z 休息需要定期手工干预,当然应该可以用自动键盘输入工具定期触发。

但哪怕如此,可能在暂停的地方会出问题,导致该地方的数据出错。

不过这也确实是一种好办法。

你给 cp 进程发送 SIGSTOP 信号也行。

什么问题?

暂停再恢复后,那个连接点处如果没处理好的话,就可能少了或者多了一个字节。

当然这是我的感觉,如果系统能够做到 “无缝” 恢复。那么就不会有问题。

怎么可能……

写个脚本加 sleep 在循环里每个文件之间

如果是单个文件很大,那就用用dd skip=xxxx bs=xxxxxxx count=1配合追加重定向之类的方法。思路就这样

若只用 shell 和 cp,可以把真实的 cp 命令写到一个临时脚本文件里,然后后台运行,捕获其进程 PID,然后间隔发送 SIGNAL 就好了。
伪代码如下:

#!/bin/bash
echo "Start Copying: $(date)"
# 创建临时脚本
real_copy=$(mktemp)
cat > $real_copy <<EOF
# 这里是真实命令
# 例如
# exec cp /some/source /some/dest
# 记住要加 exec 前缀
EOF
chmod +x $real_copy
$real_copy &
cp_pid=$!
while ps -q $cp_pid; do
sleep $((25 * 60))  # 每 25+ 暂停的 5 分钟执行一次
kill -s SIGINT $cp_pid
sleep $((5 * 60)) # 休息 5 分钟
kill -s SIGCONT $cp_pid
done
# 清除临时脚本
rm $real_copy

echo "Copied: $(date)"
1赞

当然,如果懂编程,可以更加细致的处理这个问题

同步大量数据建议使用 rsync,随时停止,还可以增量同步

10T 不算大, 可以用 rsync,不管是本地盘间同步,还是远程向本地同步,都是 ok 的,众多软件源大多是基于此实现的,可保证数据一致性,也算支持断点续传。