在 Debian 上确保 FTP 传输的数据完整性
一 基本原则与风险点
二 上传与下载的实操校验清单
三 自动化脚本示例
#!/usr/bin/env bash
set -Eeuo pipefail
HOST="ftp.example.com"
USER="user"
PASS="pass"
REMOTE="/path/file.iso"
LOCAL="./file.iso"
HASH="sha256" # 可选:md5/sha1/sha256
# 1) 获取远端大小
remote_size=$(lftp -u "$USER,$PASS" -e "ls -l '$REMOTE'; bye" "$HOST" | awk '{print $5; exit}')
# 2) 下载(二进制)
lftp -u "$USER,$PASS" -e "binary; get '$REMOTE' -o '$LOCAL'; bye" "$HOST"
# 3) 获取远端哈希(若支持;不支持则跳过)
remote_hash=$(lftp -u "$USER,$PASS" -e "quote $HASH '$REMOTE'; bye" "$HOST" 2>/dev/null | awk '{print $1; exit}')
# 4) 本地哈希
local_hash=$($HASH "$LOCAL" | awk '{print $1}')
# 5) 校验
[ "$remote_size" -eq "$(stat -c%s "$LOCAL")" ] || { echo "Size mismatch"; exit 1; }
if [ -n "$remote_hash" ]; then
[ "$local_hash" = "$remote_hash" ] || { echo "Hash mismatch"; exit 1; }
fi
echo "OK: size=$remote_size hash=$local_hash"
#!/usr/bin/env bash
set -Eeuo pipefail
URL="ftp://user:pass@ftp.example.com/path/file.iso"
LOCAL="./file.iso"
# 若本地存在且大小匹配则跳过
if [ -f "$LOCAL" ]; then
remote_size=$(lftp -u "user,pass" -e "ls -l '/path/file.iso'; bye" "ftp.example.com" | awk '{print $5; exit}')
[ "$remote_size" -eq "$(stat -c%s "$LOCAL")" ] && { echo "Already complete"; exit 0; }
fi
# 断点续传(二进制)
wget --continue --ftp-user="$USER" --ftp-password="$PASS" -O "$LOCAL" "$URL"
# 最终大小校验
remote_size=$(lftp -u "user,pass" -e "ls -l '/path/file.iso'; bye" "ftp.example.com" | awk '{print $5; exit}')
[ "$remote_size" -eq "$(stat -c%s "$LOCAL")" ] || { echo "Size mismatch after transfer"; exit 1; }
echo "OK: size=$remote_size"
四 更稳妥的替代方案
五 常见陷阱与排查要点