本文目录导读:

在Shell脚本中校验文件完整性,最常用的方法是通过哈希值(Hash) 进行计算和比对,以下是几种常用的实现方案,按推荐程度排序:
使用校验和命令(最常用)
生成/验证 sha256 哈希
#!/bin/bash
FILE_PATH="/path/to/your/file"
EXPECTED_HASH="your_expected_hash_value_here"
# 计算文件哈希
CALCULATED_HASH=$(sha256sum "$FILE_PATH" | awk '{print $1}')
# 比对哈希值
if [ "$CALCULATED_HASH" = "$EXPECTED_HASH" ]; then
echo "✓ 文件完整性验证通过"
else
echo "✗ 文件完整性验证失败"
echo "期望值: $EXPECTED_HASH"
echo "实际值: $CALCULATED_HASH"
exit 1
fi
使用 shasum(兼容性更好)
#!/bin/bash
FILE=$1
EXPECTED=$2
# 支持 sha1/sha256/sha512
if echo "$EXPECTED $FILE" | sha256sum -c --status; then
echo "文件完整"
else
echo "文件已损坏"
exit 1
fi
批量文件校验(使用校验和文件)
创建校验和文件
#!/bin/bash
# 为目录下所有文件生成校验和
find /data/files -type f -name "*.dat" -exec sha256sum {} \; > checksums.sha256
批量验证
#!/bin/bash
CHECKSUM_FILE="checksums.sha256"
# 静默模式检查
if sha256sum -c --quiet "$CHECKSUM_FILE"; then
echo "所有文件完整性验证通过"
else
echo "发现文件完整性异常,详情如下:"
sha256sum -c "$CHECKSUM_FILE" | grep -v "OK$"
exit 1
fi
更安全的校验函数(支持多种算法)
#!/bin/bash
check_file_integrity() {
local file=$1
local expected=$2
local algorithm=${3:-sha256} # 默认使用sha256
case $algorithm in
md5)
actual=$(md5sum "$file" | awk '{print $1}')
;;
sha1)
actual=$(sha1sum "$file" | awk '{print $1}')
;;
sha256)
actual=$(sha256sum "$file" | awk '{print $1}')
;;
sha512)
actual=$(sha512sum "$file" | awk '{print $1}')
;;
*)
echo "不支持的算法: $algorithm"
return 2
;;
esac
if [[ "$actual" == "$expected" ]]; then
return 0 # 成功
else
echo "期望: $expected"
echo "实际: $actual"
return 1 # 失败
fi
}
# 使用示例
if check_file_integrity "data.bin" "abc123..." "sha256"; then
echo "验证成功"
else
echo "验证失败"
fi
多种算法轮换校验(高安全性)
#!/bin/bash
robust_checksum() {
local file=$1
# 使用多种算法校验
local sha256=$(sha256sum "$file" | awk '{print $1}')
local b2sum_val=$(b2sum "$file" 2>/dev/null | awk '{print $1}' || echo "N/A")
echo "SHA256: $sha256"
echo "BLAKE2: $b2sum_val"
# 保存到文件
echo "$sha256 $file" > "${file}.sha256"
[ "$b2sum_val" != "N/A" ] && echo "$b2sum_val $file" > "${file}.b2"
}
包含错误处理的完整示例
#!/bin/bash
set -euo pipefail
validate_file_integrity() {
local file=$1
local hash_file=""
local hash_value=""
# 参数检查
if [ ! -f "$file" ]; then
echo "错误: 文件 '$file' 不存在" >&2
return 1
fi
# 尝试查找关联的哈希文件
for ext in sha256 sha256sum sha256.txt; do
if [ -f "${file}.${ext}" ]; then
hash_file="${file}.${ext}"
break
fi
done
if [ -n "$hash_file" ]; then
# 从哈希文件读取并验证
if sha256sum -c "$hash_file" --status 2>/dev/null; then
echo "✓ 文件 '$file' 验证通过"
return 0
else
echo "✗ 文件 '$file' 验证失败" >&2
return 1
fi
else
echo "警告: 未找到哈希文件,仅计算哈希值"
sha256sum "$file"
return 2
fi
}
# 主程序
main() {
local exit_code=0
if [ $# -eq 0 ]; then
echo "用法: $0 <文件1> [文件2 ...]"
exit 1
fi
for file in "$@"; do
validate_file_integrity "$file" || exit_code=$?
done
exit $exit_code
}
main "$@"
不同场景的选择建议
| 场景 | 推荐算法 | 命令 | 说明 |
|---|---|---|---|
| 快速校验 | MD5 | md5sum |
不推荐安全场景 |
| 通用场景 | SHA-256 | sha256sum |
推荐,平衡速度和安全性 |
| 高安全需求 | SHA-512 | sha512sum |
更安全,但稍慢 |
| 法律合规 | SHA-256/512 | sha256sum |
符合NIST标准 |
| 文件分发校验 | GPG签名 | gpg --verify |
支持数字签名验证 |
实际使用建议
- 优先使用 SHA-256:速度和安全性的最佳平衡
- 使用 --quiet 或 --status:避免不必要的输出
- 批量处理时使用校验和文件:提高效率
- 定期验证:在定时任务中增加校验流程
选择哪种方法取决于你的具体需求:如果只是简单的文件完整性检查,SHA-256 足够;如果是高安全性的软件分发,建议使用 GPG 签名验证。