linux下生成补丁、打补丁
文章目录
- 1. 单个文件操作
- 1.1 生成补丁- `diff` 命令
- 1.2 打补丁 `patch` 命令
- 1.3 完整示例
- 1.3.1 原始文件
- 1.3.2 修改文件
- 1.3.3 生成补丁
- 1.3.4 使用patch命令打补丁
- 1.3.5 反向修复:卸载补丁,还原版本
- 2. 目录操作
- 2.1 生成补丁- `diff` 命令
- 2.2 打补丁 `patch` 命令
- 2.3 完整示例
- 2.3.1 创建目录和文件
- 2.3.2 生成补丁
- 2.3.3 使用patch命令打补丁
- 2.3.4 反向修复:卸载补丁,还原版本
- 3 diff 命令
- 3.1 diff 命令常用选项
- 3.2 diff 命令三种格式
- 3.2.1 正常格式
- 3.2.2 上下文格式(Context Diff)
- 3.2.3 统一格式(Unified Diff)
- 3.2.4 三种格式的区别
- 4 patch 命令
1. 单个文件操作
1.1 生成补丁- diff
命令
在 Linux 中,打补丁通常使用 patch
命令,结合 diff
命令来生成补丁文件。以下是如何使用这些工具的详细说明及示例。
假设你有两个文件 file1.txt
和 file2.txt
,你想要生成一个补丁文件 patch.diff
,可以使用以下命令:
diff -u file1.txt file2.txt > patch.diff
这里 -u
表示输出统一格式的差异。
1.2 打补丁 patch
命令
假设你要将 patch.diff
应用到原始的 file1.txt
上,使用以下命令:
patch < patch.diff
这将修改 file1.txt
,使其内容变成与 file2.txt
相同的内容。
1.3 完整示例
以下是一个完整的示例,包括创建原始文件、修改文件、生成补丁和应用补丁。
1.3.1 原始文件
echo "Hello, World!" > file1.txt
1.3.2 修改文件
echo "Hello, Linux World!" > file2.txt
1.3.3 生成补丁
diff -u file1.txt file2.txt > patch.diff
1.3.4 使用patch命令打补丁
首先,确保 file1.txt
是未修改的版本,可以先备份或删除 file1.txt
,然后用原始内容重新创建:
# 覆盖 file1
patch < patch.diff
# 额外生成 file1 备份
patch < patch.diff
1.3.5 反向修复:卸载补丁,还原版本
patch -R < patch.diff
- -R(reverse)反向修复
- -E修复后如果文件为空,则删除该文件
2. 目录操作
要在两个目录中生成补丁文件并打补丁,可以使用 diff 和 patch 命令,特别是在有多个文件和子目录的情况下。下面是详细步骤,包括如何生成补丁和如何应用补丁。
2.1 生成补丁- diff
命令
使用 diff 命令生成目录之间的补丁文件。假设你有两个目录 dir1(原始目录)和 dir2(修改后的目录),可以使用以下命令生成补丁:
diff -urN dir1 dir2 > changes.patch
- -u:生成统一上下文格式的输出。
- -r:递归比较两个目录及其子目录中的文件。
- -N:如果某个文件在一个目录中存在而在另一个目录中不存在,视为一个新的空文件。
2.2 打补丁 patch
命令
要将补丁应用到原始目录中,可以使用 patch 命令。首先确保当前目录是包含要修改的文件的母目录。然后使用以下命令:
patch -p1 < changes.patch
选项说明:
- -p1:表示补丁中路径的前缀应该被去掉一个目录层级。你可能需要根据补丁文件中的路径调整这个值:
- 如果补丁文件的路径是 dir1/file1.txt,则使用 -p0。
- 如果路径是 file1.txt,则使用 -p1。
2.3 完整示例
以下是一个完整的示例,包括创建原始文件、修改文件、生成补丁和应用补丁。
2.3.1 创建目录和文件
mkdir dir1 dir2
# 在 dir1 中创建文件和子目录
echo "Hello, World!" > dir1/file1.txt
echo "This is file2." > dir1/file2.txt
mkdir dir1/subdir
echo "Inside subdir." > dir1/subdir/file3.txt
# 在 dir2 中修改文件并添加文件
echo "Hello, Linux World!" > dir2/file1.txt # 修改
echo "This is file2 updated." > dir2/file2.txt # 修改
mkdir dir2/subdir # 添加子目录
echo "New file in subdir." > dir2/subdir/file4.txt # 新增文件
2.3.2 生成补丁
diff -urN dir1 dir2 > changes.patch
2.3.3 使用patch命令打补丁
首先,回到 dir1 的目录结构,准备应用补丁:
cd dir1
patch -p1 < ../changes.patch
# 如果在 dir1 上一级目录,执行
patch -p0 < ../changes.patch
2.3.4 反向修复:卸载补丁,还原版本
cd dir1
patch -p1 -R < linux.patch
# 如果在 dir1 上一级目录,执行
patch -p0 -R < linux.patch
总结
- 使用 diff -urN 生成目录间的补丁文件。
- 使用 patch -p1 将补丁应用到原始目录中。
3 diff 命令
3.1 diff 命令常用选项
- -u 输出统一内容的头部信息(打补丁使用),计算机知道是哪个文件需要修改
- -r 递归对比目录中的所有资源(可以对比目录)
- -a 所有文件视为文本(包括二进制程序)
- -N 无文件视为空文件(空文件怎么变成第二个文件)
- -N选项备注说明:
- A目录下没有txt文件,B目录下有txt文件
- diff比较两个目录时,默认会提示txt仅在B目录有(无法对比差异,修复文件)
- diff比较时使用N选项,则diff会拿B下的txt与A下的空文件对比,补丁信息会明确
3.2 diff 命令三种格式
diff 命令用于比较两个文件的差异,并以不同的格式输出结果。以下是 diff 命令的三种主要输出格式及其区别和示例。
三种格式:
- 正常格式(Normal Diff)
- 上下文格式(Context Diff)
- 统一格式(Unified Diff)
创建两个文件,内容分别如下;
# file1
$ cat file1
1
2
3
4
5
6
7
8
9
0
# file2
$ cat file2
1
2
3
4
8
6
7
8
9
0
3.2.1 正常格式
正常格式是 diff 的默认输出格式,它直接显示差异的行和指示符,例如:
- a 表示添加(addition)。
- c 表示更改(change)。
- d 表示删除(deletion)。
$ diff file1 file2
5c5,6 # file1 显示第5行,c表示change,file2显示第5,6行
< 5 # < 表示第一个文件
---
> 8 # 表示第二个文件
>
3.2.2 上下文格式(Context Diff)
上下文格式通过-c
选项启用,它会显示差异的上下文信息,帮助用户更好地理解差异的位置。
$ diff -c file1 file2
*** file1 Tue Feb 18 17:27:27 2025 # *** 表示第一个文件文件名和时间戳
--- file2 Tue Feb 18 17:27:48 2025 # --- 表示第二个文件文件名和时间戳
*************** # 表示差异块的开始
*** 2,8 **** # 下面显示的是第一个文件的第2到第8行
2
3
4
! 5 # !表示该行有差异
6
7
8
--- 2,9 ---- # 下面显示的是第一个文件的第2到第9行
2
3
4
! 8 # !表示该行有差异
! # !表示该行有差异
6
7
8
3.2.3 统一格式(Unified Diff)
合并格式通过 -u
选项启用,是目前最常用的格式,因为它简洁且易于阅读,常用于版本控制系统。
$ diff -u file1 file2
--- file1 2025-02-18 17:27:27.539164611 +0800 # --- 表示第一个文件文件名和时间戳
+++ file2 2025-02-18 17:27:48.507501020 +0800 # +++ 表示第一个文件文件名和时间戳
@@ -2,7 +2,8 @@ # -和+分别表示两个文件差异行所在的行范围
2
3
4
-5 # - 表示第一个文件中删除
+8 # + 表示第二个文件中添加
+ # + 表示第二个文件中添加
6
7
8
3.2.4 三种格式的区别
格式 | 特点 | 示例 |
---|---|---|
正常格式 | 简洁,只显示差异行 | 5c5,6 |
上下文格式 | 显示差异的上下文,便于理解 | *** 和 — 包裹上下文 |
合并格式 | 简洁且易于阅读,适合版本控制系统 | @@ 包裹差异范围 |
4 patch 命令
常用选项:
- -R(reverse)反向修复,假设修补数据是由新旧文件交换位置而产生。
- -E修复后如果文件为空,则删除该文件。若修补过后输出的文件其内容是一片空白,则移除该文件。
- -b 备份每一个原始文件。
- -p<剥离层级>或–strip=<剥离层级> 设置欲剥离几层路径名称。
- –verbose 详细显示指令的执行过程。