Scp
SCP 传输尚未完成,文件却被 mv 提前移动,导致备份不完整。这是典型的竞态条件(race condition)问题,尤其在脚本自动化中很常见
SCP 是异步写入的,文件在传输过程中就已经出现在目标路径(虽然是 .filepart 或临时名),如果此时你脚本里用了 mv 或 rsync 去“备份”它,就可能拿到一个不完整的文件。
#!/bin/bash
REMOTE_USER="user"
REMOTE_HOST="remote.example.com"
REMOTE_FILE="/data/backup.tar.gz"
LOCAL_DIR="/local/backup/incoming"
FINAL_DIR="/local/backup/final"
# 使用 scp 传到临时目录
scp "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_FILE}" "${LOCAL_DIR}/backup.tar.gz.tmp"
# 确认传输成功后再原子移动
if [[ $? -eq 0 ]]; then
mv "${LOCAL_DIR}/backup.tar.gz.tmp" "${FINAL_DIR}/backup.tar.gz"
echo "Backup complete and moved to final location."
else
echo "SCP failed, not moving incomplete file."
exit 1
fi
scp fufnc
exec 200>"$HOME/.lock/backup.lock"
flock 200
scp backup.tar.gz user@remote:/backup/
flock -u 200
mv func
exec 200>"$HOME/.lock/backup.lock"
flock 200
mv backup.tar.gz /done/
flock -u 200
一个更稳的写法(推荐你用
(
flock -n 200 || exit 1
scp backup.tar.gz user@remote:/backup/
) 200>"$HOME/.lock/backup.lock"
==