文本文件打补丁(Patch):
补丁文件本质上是一个差异文件 (diff),记录了两个版本之间的不同之处。通常使用 diff 命令生成,用 patch 命令应用。
生成补丁
# 比较两个文件
diff -u oldfile.c newfile.c > fix.patch
# 比较两个目录(递归)
diff -urN old_dir/ new_dir/ > big_fix.patch
-u:生成统一格式(unified diff),最常用;-r:递归比较子目录;-N:把缺失的文件视为空文件,便于新增/删除文件的处理。
应用补丁
文件级补丁
# 应用补丁到当前目录的文件
patch < fix.patch
# 或指定目标文件
patch original_file.c < fix.patch
目录级补丁,如内核补丁
cd linux-source/
patch -p1 < ../my_kernel_fix.patch
关键参数 -p1 :
补丁文件中路径可能包含前缀(如 a/kernel/sched.c 和 b/kernel/sched.c)。
-p1 表示忽略第一层目录(即去掉 a/ 和 b/),直接在当前目录下找 kernel/sched.c。
-p0 表示不剥离任何路径(使用完整路径)。
| 选项 | 说明 |
|---|---|
-pN |
剥离 N 层路径前缀 |
--dry-run |
试运行,不实际修改文件,用于测试是否能成功应用 |
-f 或 --force |
强制应用,跳过交互 |
-R |
反向应用(撤销补丁) |
diff 和 patch 的设计原理
diff比较的是文本行(line-based),逐行分析内容差异;- 它输出的是"哪些行被添加、删除或修改了";
patch则根据这些"行级指令"去修改目标文件。
而二进制文件没有"行"的概念 ,其内容是字节流,任意一个字节变化都可能破坏整个文件结构。因此,传统的 unified diff(即 .patch 文件)无法描述二进制差异。
二进制文件打补丁
使用 bsdiff / bspatch
这是专门为二进制文件设计的差分/打补丁工具。
-
bsdiff:生成两个二进制文件之间的最小差异补丁; -
bspatch:用该补丁将旧文件升级为新文件。生成补丁(耗时可能较长)
bsdiff old_app.bin new_app.bin update.bspatch
应用补丁(很快)
bspatch old_app.bin updated_app.bin update.bspatch
验证是否一致
cmp new_app.bin updated_app.bin # 应无输出(完全相同)
cmp 比较两个文件
- 作用 :以字节为单位(byte-by-byte)比较两个文件;
- 默认行为 :
- 如果两个文件完全相同 → 不输出任何内容,返回退出状态码 0;
- 如果存在差异 → 输出第一个不同字节的位置和值 ,并返回非零状态码(通常是 1)。
| 选项 | 说明 |
|---|---|
-s, --quiet, --silent |
静默模式:不输出任何信息,仅通过退出码判断是否相同(非常适合脚本) |
-l, --verbose |
列出所有不同字节的位置和值(以十进制字节偏移 + 八进制值显示) |
-n N |
最多比较前 N 个字节 |
-i SKIP |
跳过每个文件开头的 SKIP 字节再比较 |
静默比较(脚本中最常用)
if cmp -s new_app.bin updated_app.bin; then
echo "文件一致!"
else
echo "文件不同!"
fi