首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Linux 补丁文件应用命令 patch

描述

patch命令用于将补丁文件应用到源代码文件中,以实现对源代码的修改。补丁文件通常是由开发者或者社区提供的,用于修复源代码中的错误或者添加新功能。

语法

patch [选项] [源代码文件] [补丁文件]

-p:指定路径剥离级别,用于去除补丁文件中的路径前缀。通常在补丁文件中会包含源代码文件的相对路径,使用该选项可以去除这些路径前缀。

-d :指定工作目录,用于在指定目录下执行补丁操作。

-N:允许添加新文件,即如果补丁文件中包含新文件,patch命令会将其添加到源代码中。

-R:撤销已应用的补丁,即将补丁文件中的修改恢复到源代码文件中。

-s:安静模式,即不显示详细的操作信息。

-i :指定补丁文件的路径。

root@ubuntu:/home/ubuntu# patch --help

Usage: patch [OPTION]... [ORIGFILE [PATCHFILE]]

Input options:

-p NUM --strip=NUM Strip NUM leading components from file names.

-F LINES --fuzz LINES Set the fuzz factor to LINES for inexact matching.

-l --ignore-whitespace Ignore white space changes between patch and input.

-c --context Interpret the patch as a context difference.

-e --ed Interpret the patch as an ed script.

-n --normal Interpret the patch as a normal difference.

-u --unified Interpret the patch as a unified difference.

-N --forward Ignore patches that appear to be reversed or already applied.

-R --reverse Assume patches were created with old and new files swapped.

-i PATCHFILE --input=PATCHFILE Read patch from PATCHFILE instead of stdin.

Output options:

-o FILE --output=FILE Output patched files to FILE.

-r FILE --reject-file=FILE Output rejects to FILE.

-D NAME --ifdef=NAME Make merged if-then-else output using NAME.

--merge Merge using conflict markers instead of creating reject files.

-E --remove-empty-files Remove output files that are empty after patching.

-Z --set-utc Set times of patched files, assuming diff uses UTC (GMT).

-T --set-time Likewise, assuming local time.

--quoting-style=WORD output file names using quoting style WORD.

Valid WORDs are: literal, shell, shell-always, c, escape.

Default is taken from QUOTING_STYLE env variable, or 'shell' if unset.

Backup and version control options:

-b --backup Back up the original contents of each file.

--backup-if-mismatch Back up if the patch does not match exactly.

--no-backup-if-mismatch Back up mismatches only if otherwise requested.

-V STYLE --version-control=STYLE Use STYLE version control.

STYLE is either 'simple', 'numbered', or 'existing'.

-B PREFIX --prefix=PREFIX Prepend PREFIX to backup file names.

-Y PREFIX --basename-prefix=PREFIX Prepend PREFIX to backup file basenames.

-z SUFFIX --suffix=SUFFIX Append SUFFIX to backup file names.

-g NUM --get=NUM Get files from RCS etc. if positive; ask if negative.

Miscellaneous options:

-t --batch Ask no questions; skip bad-Prereq patches; assume reversed.

-f --force Like -t, but ignore bad-Prereq patches, and assume unreversed.

-s --quiet --silent Work silently unless an error occurs.

--verbose Output extra information about the work being done.

--dry-run Do not actually change any files; just print what would happen.

--posix Conform to the POSIX standard.

-d DIR --directory=DIR Change the working directory to DIR first.

--reject-format=FORMAT Create 'context' or 'unified' rejects.

--binary Read and write data in binary mode.

--read-only=BEHAVIOR How to handle read-only input files: 'ignore' that they

are read-only, 'warn' (default), or 'fail'.

-v --version Output version info.

--help Output this help.

Report bugs to .

示例

应用补丁文件:

patch -p1 < patchfile

该命令将补丁文件patchfile应用到当前目录下的源代码文件中。

指定工作目录:

patch -d /path/to/directory -p1 < patchfile

该命令将补丁文件patchfile应用到/path/to/directory目录下的源代码文件中。

撤销已应用的补丁:

patch -R < patchfile

该命令将补丁文件patchfile中的修改恢复到源代码文件中。

注意事项

在使用Linux Shell中的patch命令时,有一些注意事项需要注意:

确保补丁文件与源代码文件匹配:补丁文件是根据源代码文件生成的,因此确保补丁文件与要应用的源代码文件是匹配的。如果补丁文件与源代码文件不匹配,将会出现错误。

使用正确的剥离路径级别:如果补丁文件中的路径与当前目录下的源代码文件路径不匹配,需要使用-p选项来指定剥离路径的级别。剥离路径级别表示从补丁文件中剥离的路径层级数。例如,如果补丁文件中的路径是a/b/c/file.txt,而源代码文件在当前目录下,则需要使用-p2选项来剥离两级路径。

注意撤销已应用的补丁:使用-R选项可以撤销已经应用的补丁。在撤销补丁时,需要确保补丁文件与已应用的补丁完全匹配。

使用安静模式:使用-s选项可以进入安静模式,不显示详细的输出信息。这在批量应用补丁时可以减少输出信息的干扰。

允许添加新文件:使用-N选项可以允许添加新文件。有时候,补丁文件可能包含新的文件,使用该选项可以允许添加这些新文件。

注意补丁文件的格式:补丁文件应该按照特定的格式进行编写,包含必要的行信息。如果补丁文件的格式不正确,例如缺少必要的行信息,将会出现错误。

底层实现

Linux Shell中的patch命令底层实现主要是通过diff和patch工具来完成。

diff工具:diff工具用于比较两个文件或目录的差异,并生成补丁文件。通过比较源文件和目标文件的内容,diff工具会生成一系列描述差异的行。这些行包含了要添加、删除或修改的内容。diff工具支持多种格式的补丁文件生成,例如普通格式、上下文格式和统一格式。

patch工具:patch工具用于根据补丁文件来应用补丁。它会读取补丁文件中的描述差异的行,并根据这些行来修改源文件。patch工具会根据补丁文件中的路径信息和修改操作来定位源文件,并将修改应用到相应的位置。当应用补丁时,patch工具会检查源文件的内容和补丁文件中描述的差异是否匹配,如果匹配则应用补丁,否则会报错。

在底层实现中,patch命令会调用diff工具生成补丁文件,并使用patch工具来应用补丁文件。patch命令会解析用户提供的选项和参数,并将其传递给diff和patch工具进行相应的操作。通过这种方式,patch命令实现了对源文件的修改和更新。

需要注意的是,patch命令底层实现可能会因不同的操作系统或发行版而有所差异,但基本原理和使用方法是相似的。

创建补丁

创建补丁最简单的办法是通过两份代码进行,一份源码,另一份是加进了所修改部分的源代码。原来的起名 linux-x.y.z,而修改过的就起名为 linux。然后利用下面的命令通过这两份代码创建补丁:

diff -urN linux-x.y.z/ linux/ > my-patch

通过-u参数指定使用特殊的 dif 输出格式。否则得到的 patch 格式怪异,一般人都无法看懂。

-r 参数保证会历所有子目录进行操作。

-N 参数指明做出修改的源代码中所有新加的文件在 dif 作时会含在。另外,

如想对一个单独的文件进行 dif,你也可以这么做 :

diff -u linux-x.y.z/some/fle linux/some/file > my-patch

注意,在你自己代码所在的目录下执行 diff 很重要。这样创建的补丁别人用起来更方便,哪怕他们的目录名字叫 difer 也没问题。执行一个这样生成的补丁,只需要在你自己代码树的根目录执行下列命令就可以了 :

patch -pl < .../my-patch

在这个例子中,补丁的名字叫 my-patch,它位于当前目录的上一级目录中。-p1参数用来剥去补丁中头一个目录的名称。这么做的好处是可以在打补丁的时候忽略创建补丁的人的目录命名习惯。

diffstat 是一个很有用的工具,它可以列出补丁所引起的变更的统计(加入或移去的代码行)。输出关于补丁的信息,执行 :

diffstat -pl my-patch

在贴出自己的补丁时,附带上这份信息往往会很有用。由于 patch(1)会忽略第一个diff之前的所有内容,所以你甚至可以在 patch 的最前面直接加上简短的说明。

用Git 创建补丁

如果你用 Git 管源代码,需要使用Git创建补丁。用 Git 创建补并不是什么难事,只需要两个过程。首先,你必须是修改者,然后在本地提交你的修改。把修改提交到Git 树与提交到标准的源代码树并没有什么两样。你根本不需要专门做任何事情去编辑存放在 Git 中的文件。你做出修改后,就需要把所做的修改提交到你的 Git 版库:

git commit -a

-a 数表示提交所有的修改。如果你仅仅想提交某个指定文件的修改,则如下示例:

git commit some/file.c

但是即使有了 -a 参数,Git 并不立即提交新文件,直到把它们添加到版本库中才提交。要增加一个文件,然后再提交,则输入如下两条命令 :

git add some/other/file.c

git commit -a

当执行 Git 的 commit 命令时,Git 会要求输入一个更改日志。你应该尽量填写的详细和完整清楚地解释修改缘由。当在源码树中有一个(或两个)提交时,可以为每个提交创建一个补丁,可以像上面章节所描述的那样来处理这个补丁:

git format-patch origin

对于所有的提交,这样产生的补丁放在你的版本库中而不是原始树中。Git 产生的补丁位于源代码树的根目录中。如果只想为最后第 N 次提交产生补丁,则可以执行下列命令:

git format-patch -N

例如,下面的命令只为最后一次提交产生一个补丁:

git format-patch -1

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OGdQxnjrMADhsc0USPPl_0-g0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券