1. 简述
在我们应用Linux系统或基于Linux系统做一些软件应用开发时,经常会遇到需要将文件的改动记录下来,并且讲这些改动和差异应用到其他的Linux系统时,我们会用到diff和patch指令。
在Linux中,diff和patch是两个非常有用的命令行工具,它们通常一起使用,用于比较文件差异和应用这些差异。这两个工具在软件开发、版本控制和系统管理中特别有用。
2. diff指令(生成补丁)
diff命令用于比较两个文件的差异。它将显示两个文件之间的不同之处,并输出一个差异脚本。
diff指令的语法如下。
diff [options] file1 file2
其常用的选项如下。
-u:以统一格式输出差异,这是创建补丁文件的常用格式。
-r:递归地比较两个目录中的文件。
-c:以上下文格式输出差异。
如果我们想要比较两个文件的差异,我们可以参考如下指令。
diff -u file1.txt file2.txt
如果我们要比较的是文件夹,而且文件夹中存在一些文件和子目录,那么我们可以按照如下指令完成差异的比较。
diff -ru dir1 dir2
3. patch(打补丁)
patch指令用于打补丁,即将diff生成的补丁应用到其他原始的文件中,是的打补丁后的文件和之前修改的文件相匹配。这一种场景经常用在发布一些内核文件以后,定期迭代、增删改查一些东西,无需再发布内核,只需要每次发布补丁即可。
patch指令的语法如下。
patch [options] originalfile < patchfile
patch [options] -p[num] < patchfile
常用的options如下,其他参数可参照文末附录:
-p<n>:指定路径剥离级别,表示去除路径中前面的 <n> 个目录名。通常,-p1 是最常用的选项,用于去除路径中的第一个目录名。 patch -p 后面是不能带负数 的。不使用 p 参数的时候,patch 命令会 忽略 任何目录,直接使用文件。
-i <补丁文件>:指定要应用的补丁文件。
-d <目录>:指定工作目录,用于指定补丁文件和源文件所在的目录。
举个例子来说明,假设补丁文件中的路径为 d0/d1/d2/file.txt,使用不同的 -p 参数来打补丁的效果如下:
patch -p0 < 补丁文件名
补丁文件中的完整路径d0/d1/d2/file.txt将会被保留, file.txt 将被应用到当前工作目录下的d0/d1/d2/file.txt文件上。
使用 -p1 参数:
patch -p1 < 补丁文件名
补丁文件中的路径d0/d1/d2/file.txt的第一个目录名d0将会被剥离,只剩下 d1/d2/file.txt。这样,file.txt 将被应用到当前工作目录下的d1/d2/file.txt文件上。
应用补丁到文件,可以执行如下指令。
patch original.txt < patchfile.txt
应用补丁到文件夹,可以参照如下指令。
patch -p1 < patchfile.txt
4. 附录
-b或--backup 备份每一个原始文件。
-B<备份字首字符串>或--prefix=<备份字首字符串> 设置文件备份时,附加在文件名称前面的字首字符串,该字符串可以是路径名称。
-c或--context 把修补数据解译成关联性的差异。
-d<工作目录>或--directory=<工作目录> 设置工作目录。
-D<标示符号>或--ifdef=<标示符号> 用指定的符号把改变的地方标示出来。
-e或--ed 把修补数据解译成ed指令可用的叙述文件。
-E或--remove-empty-files 若修补过后输出的文件其内容是一片空白,则移除该文件。
-f或--force 此参数的效果和指定-t参数类似,但会假设修补数据的版本为新 版本。
-F<监别列数>或--fuzz<监别列数> 设置监别列数的最大值。
-g<控制数值>或--get=<控制数值> 设置以RSC或SCCS控制修补作业。
-i<修补文件>或--input=<修补文件> 读取指定的修补问家你。
-l或--ignore-whitespace 忽略修补数据与输入数据的跳格,空格字符。
-n或--normal 把修补数据解译成一般性的差异。
-N或--forward 忽略修补的数据较原始文件的版本更旧,或该版本的修补数据已使 用过。
-o<输出文件>或--output=<输出文件> 设置输出文件的名称,修补过的文件会以该名称存放。
-p<剥离层级>或--strip=<剥离层级> 设置欲剥离几层路径名称。
-f<拒绝文件>或--reject-file=<拒绝文件> 设置保存拒绝修补相关信息的文件名称,预设的文件名称为.rej。
-R或--reverse 假设修补数据是由新旧文件交换位置而产生。
-s或--quiet或--silent 不显示指令执行过程,除非发生错误。
-t或--batch 自动略过错误,不询问任何问题。
-T或--set-time 此参数的效果和指定-Z参数类似,但以本地时间为主。
-u或--unified 把修补数据解译成一致化的差异。
-v或--version 显示版本信息。
-V<备份方式>或--version-control=<备份方式> 用-b参数备份目标文件后,备份文件的字尾会被加上一个备份字符串,这个字符串不仅可用-z参数变更,当使用-V参数指定不同备份方式时,也会产生不同字尾的备份字符串。
-Y<备份字首字符串>或--basename-prefix=--<备份字首字符串> 设置文件备份时,附加在文件基本名称开头的字首字符串。
-z<备份字尾字符串>或--suffix=<备份字尾字符串> 此参数的效果和指定-B参数类似,差别在于修补作业使用的路径与文件名若为src/linux/fs/super.c,加上backup/字符串后,文件super.c会备份于/src/linux/fs/backup目录里。
-Z或--set-utc 把修补过的文件更改,存取时间设为UTC。
--backup-if-mismatch 在修补数据不完全吻合,且没有刻意指定要备份文件时,才备份文件。
--binary 以二进制模式读写数据,而不通过标准输出设备。
--help 在线帮助。
--nobackup-if-mismatch 在修补数据不完全吻合,且没有刻意指定要备份文件时,不要备份文件。
--verbose 详细显示指令的执行过程。