patch 命令
用途
对文件应用更改。
语法
补丁 [ -b [ -B 前缀 ] ] [ -f ] [ -l ] [ -N ] [ -R ] [ -s ] [ -v ] [ -c | -e | -n | -u ] [ -d 目录 ] [ -D 定义 ] [ -F 数量 ] [ -i PatchFile ] [ -o OutFile ] [ -p 数量 ] [ -r RejectFile ] [ -x 数量 ] [ 文件 ]
描述
patch 命令读取如何更改文件 的源文件指示信息,然后应用这些更改。 源文件包含由diff -c 或-u命令 生成的差异列表(或diff列表),以及一组或多组diff命令输出(通常称为hunks)。
patch 命令跳过补丁文件中的任何前导文本,然后应用实际的差异列表,并且跳过任何后续文本。 因此,可用作包含差异列表的补丁文件或消息,此时 patch 命令仍将有效。 在这种情况下,如果整个差异列表使用一致的数量缩进,patch 命令也会调整其间距。
要更改原始文件中的行范围,每一补丁中的块 (hunk) 必须为单独的差异列表。 补丁内连续块 (hunk) 的行号必须以升序方式出现。
文件名的确定
如果没有指定 File 参数,要获得供编辑的文件名,patch 命令会执行下面的步骤:
- 在上下文差异列表头中,
- 如果差异的类型是复制上下文,那么文件名由以 ***(3 个星号)或 —-(3 个短划线)开头的行确定。 以 *** 开头的行表示获取补丁 的文件,然而以 —- 开头的行表示应该应用补丁的文件名。 选择存在文件的最短名称。
- 如果差异的类型是统一上下文,那么文件名由以 ---(3 个短划线)或 +++(3 个加号)开头的行确定。 以 --- 开头的行指示从中获取补丁的文件的名称,而以 +++ 开头的行指示要对其应用这些补丁的文件的名称。 选择存在文件的最短名称。
- 如果有Index:行,补丁命令会尝试使用该行的文件名。
- 上下文差异标头优先于Index:线。
- 如果不能从前导文本中确定文件名,那么 patch 命令将提示输入要打补丁的文件的名称。
- 如果不能找到原始文件,但是有适合的 SCCS 或 RCS 文件可用,那么 patch 命令将尝试获取或检出文件。
- 如果前导文本包含Prereq:行,"补丁命令从先决条件行中获取第一个单词(通常是版本号),并检查输入文件是否能找到该单词。 如果找不到, patch 命令在继续运行前会提示确认。
补丁应用程序
如果补丁文件包含不止一个补丁,patch 命令尝试应用每个差异列表,就好像它 来自于单独的补丁文件。 在这种情况下,为每个差异列表确定需要打补丁的文件名,并且审查每个差异列表前的头文本以获得如文件名和修订版级别的信息。
如果指定 -c、-e、-n 或 -u 标志,那么 patch 命令会分别将每个 hunk 中的信息解释为复制上下文差异、ed 编辑器差异、正常差异或统一上下文差异。 否则,patch 命令确定基于块 (hunk) 内信息格式的差别类型。
patch 命令通过获取块 (hunk) 的首行序号和添加或减去由于应用前一块 (hunk) 而产生的任何行偏移来搜索位置以应用每一块 (hunk)。 如果在这一行位置不可能有精确匹配,patch 命令前后搜索以获取与块 (hunk) 的内容精确匹配的行集合。
如果找不到这些位置,且如果 patch 命令正在应用上下文差异列表,patch 命令能进行非精确搜索。 fuzz factor 指定了非精确匹配的行数目。 如果模糊因子设置成 1 或者更大,patch 命令执行第二次扫描,这一次忽略上下文的第一行和最后一行。 如果没有匹配结果,且最大模糊因子设置成 2 或者更大,patch 命令执行第三次扫描,这一次会忽略上下文的前两行和最后两行。 (缺省模糊因子最大值为 2)。 如果找不到匹配的位置,patch 命令在拒绝文件中放置块 (hunk)。 创建拒绝文件时,其名称和输出文件一样,只是在文件名有后缀 .rej。 使用 -r 标志可以覆盖此命名约定。
不管补丁文件的格式如何,将按照已复制的上下文差异列表格式来编写被拒绝的块。 如果输入是正常差异或 ed 编辑器风格差异,那么拒绝文件可能包含没有使用复制上下文格式的行的差异。 拒绝文件中块 (hunk) 的行编号可能与补丁文件中的行编号不同。 这是因为拒绝文件的行编号反映了新文件而不是老文件中故障块 (hunk) 的大约位置。
当完成每块 (hunk) 后,patch 命令会告诉您该块 (hunk) 是成功还是失败。 也可以获知为每块 (hunk) 假定的新行编号。 如果这与差异列表中指定的行编号不同,就会报告偏移量。 patch 命令也说明是否使用模糊因子来进行匹配。
注意:单一的大偏移可能表示块 (hunk) 安装位置不正确。 模糊因子的使用可能表示布局不正确。
为其他用户准备补丁
准备将补丁装载给其他用户的程序员应该考虑下面的附加原则:
- 如果想两次应用同一补丁,那么 patch 命令将假定第二次应用应该是逆向补丁,并且会提示您确认此逆向。 因此,避免发送出这些逆向补丁,因为它使用户疑惑他们是否已经应用了此补丁。
- 建议保留使用最新补丁级别更新的 patchlevel.h 文件。 补丁级别可以用作所发送的补丁文件中的第一个差异列表。 如果您的补丁包含Prereq:行,用户不能乱打补丁而不会收到警告。
- 确保正确指定文件名,可以在上下文差异列表标题中指定,也可以用Index:线。 如果正在子目录中打某些补丁,请确保通知补丁用户在需要时指定 -p 标志。
- 可以发送通过比较空文件和要创建的文件的差异列表来创建文件。 但是,这个方法只有在想要创建的文件的确不存在于目标目录时才有效。
- 虽然可以将多个差异列表放置到一个文件中,但是建议将相关补丁分组到单独的文件中。
- patch 命令不能说明 ed 脚本中的行编号是否正确,只能在当它找到更改或删除命令时才能检测到正常差异列表中不正确的行编号。 使用模糊因子为 3 的上下文差异列表可能有同样的行编号问题。 除非添加了一个适当的交互式接口,在这种情形下才使用上下文差异列表来检测更改的正确性。 编译无误通常表示补丁工作正常,但是它并不表示没有错误。
- 仅当补丁应用到与生成补丁的同一版本的文件中,才能保证 patch 命令的结果是正确的。
- 如果代码重复,例如:
patch 命令不能为两个版本都打补丁。 如果 patch 命令成功,它可能补丁了错误版本但是返回了一个成功的退出状态。#ifdef ... NEWCODE #else ... OLDCODE # endif
标志
| 项 | 描述 |
|---|---|
| -b | 在应用差别前保存每个修改后文件的副本。 复制的原始文件归档时与原文件同名且添加了后缀 .orig。 如果使用那个名称的文件已经存在,它就被覆盖。 如果对同一文件应用 多个补丁,原始文件只生成一个副本(在第一次补丁时)。 如果也指定 -o OutFile 标志,就不会创建 .orig 文件。 但是如果指定文件已经存在,就创建 OutFile.orig。 |
| -B 前缀 | 指定备份文件名称的前缀。 此标志只有在和 -b 标志连接使用时才有效。 |
| -c | 将补丁文件解释为复制上下文差异列表(diff -c 或 diff -C 命令的输出)。 此标志不能与 -e、-n 或 -u 标志一起使用。 |
| -d 目录 | 在处理前,更改当前目录到指定目录。 |
| -D 定义 | 使用下面的 C 预处理器构造标记更改:Define 变量用作差分符号。 此标志只有当正常或上下文格式差异列表用作补丁文件时 才有效。 |
| -e | 将补丁文件解释成 ed 编辑器脚本。 此标志不能与 -c、-n 或 -u 标志一起使用。 |
| -f | 禁止查询用户。 要禁止注释,使用 -s 标志。 |
| -F 数量 | 设置最大模糊因子。 此标志只应用于上下文差异列表,它使 patch 命令在确定块 (hunk) 的安装位置时忽略
指定行编号。 如果未指定-F标志,默认模糊因子为 2。 该因子不能设置为超过上下文差集列表中的内容行数 (通常 3 3)。注意:较大的模糊因子 会增加错误补丁的可能性。 |
| -i PatchFile | 从指定文件,而不是从标准输入中读取补丁信息。 |
| -l | (L 的小写)使差异列表脚本中的任何空格字符序列匹配输入文件中的任何空格字符序列。 精确匹配其他字符。 |
| -n | 将脚本解释成正常差异列表。 此标志不能与 -c、-e 或 -u 标志一起使用。 |
| -N | 忽略差别已经向文件应用了的补丁。 缺省情况下,会拒绝已经应用的补丁。 |
| -o OutFile | 复制要打补丁的文件,然后应用更改,接着将修改版本写到 指定的输出文件。 单个文件的多个补丁应用于以前补丁所创建的文件的中间版本。 因此,多补丁会生成输出文件的多个连接版本。 |
| -p 数量 | 设置路径名的剥离数目,它控制如何处理在补丁文件中找到的路径名称。 如果将文件保留在与指定路径不同的目录中,此标志就有用。 剥离数目指定了
从路径名前去除多少个斜杠。 也去除所有中间的目录名。 例如,假设补丁文件指定/u/leon/src/blurf1/blurf1.c:
如果没有指定 -p 标志,只使用基本名称(最后的路径名称组件)。 此标志只有在 没有指定 File 参数时才起作用。 |
| -r RejectFile | 覆盖缺省拒绝文件名。 通过附加后缀 .rej 到原始文件名中,就形成了缺省拒绝文件名。 |
| -R | 逆向补丁脚本理解。 例如,如果从新版本到旧版本创建差异列表,使用 -R 标志使 patch 命令在应用前逆向脚本的每个部分。 以交换格式保存拒绝差别。 -R 标志不能和 ed 脚本一起使用,因为其中只有很少的信息可以重新构造逆向操作。 如果没有指定 -R 标志,patch 命令尝试以逆向理解和正常理解应用每个部分,直到成功应用补丁文件的每一部分。 如果尝试成功,提示用户确定是否应该设置 -R 标志。注意:如果此方法和第一个命令是附加命令(就是说,逆序是删除)的正常差异列表一起使用,它就不能检测逆向补丁。 因为空上下文无论在何处都匹配,所以附加总是成功的。 幸运的是,大多数补丁是添加或更改行而不是删除行。 因此大多数逆序的正常差异列表以一个删除开始,它导致故障,并且引起启发 (heuristic)。 |
| -s | 静默地进行补丁,直到发生错误。 |
| -U | 将补丁文件解释为统一上下文差异列表(指定 -u 或 -U 标志时 diff 命令的输出)。 不能将此标志与 -c、-e 或 -n 标志一起指定。 |
| -v | 显示修订版头和补丁级别。 如果 -v 标志和其他标志一起使用,就忽略其他标志。 |
| -x 数量 | 设置内部调试标志。 此标志只适用于 patch 命令开发者。 |
退出状态
返回以下退出值:
| 项 | 描述 |
|---|---|
| 重大安全事件数量 | 成功完成。 |
| 第 1 年 | 发生错误,并将一行或多行写入拒绝的文件。 |
| >1 | 发生错误。 |
示例
- 要在difflisting文件到prog.c文件,输入
patch -i difflisting prog.c - 要保存prog.c文件,输入
这适用于以下更改prog.c并保存prog.c文件中的prog.c.orig.patch -b -i difflisting prog.c - 要修补prog.c在不更改原始文件的情况下,输入
它使用prog.c作为源文件,但更改后的版本会写入名为prog.new.patch -i difflisting -o prog.new prog.c
文件
| 项 | 描述 |
|---|---|
| /usr/bin/patch | 包含 patch 命令。 |