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