diff 命令
Linux 系统中使用 diff 命令对比出新旧软件的不同,并生成补丁文件。
基本格式
[root@localhost ~]# diff 选项 old new
#比较old和new文件的不同
参数 |
描述 |
-<行数> |
指定要显示多少行的文本。此参数必须与-c或-u参数一并使用。 |
-a或--text |
diff预设只会逐行比较文本文件。 |
-b或--ignore-space-change |
不检查空格字符的不同。 |
-B或--ignore-blank-lines |
不检查空白行。 |
-c |
显示全部内文,并标出不同之处。 |
-C<行数>或--context<行数> |
与执行"-c-<行数>"指令相同。 |
-d或--minimal |
使用不同的演算法,以较小的单位来做比较。 |
-D<巨集名称>或ifdef<巨集名称> |
此参数的输出格式可用于前置处理器巨集。 |
-e或--ed |
此参数的输出格式可用于ed的script文件。 |
-f或-forward-ed |
输出的格式类似ed的script文件,但按照原来文件的顺序来显示不同处。 |
-H或--speed-large-files |
比较大文件时,可加快速度。 |
-l<字符或字符串>或--ignore-matching-lines<字符或字符串> |
若两个文件在某几行有所不同,而这几行同时都包含了选项中指定的字符或字符串,则不显示这两个文件的差异。 |
-i或--ignore-case |
不检查大小写的不同。 |
-l或--paginate |
将结果交由pr程序来分页。 |
-n或--rcs |
将比较结果以RCS的格式来显示。 |
-N或--new-file |
在比较目录时,若文件A仅出现在某个目录中,预设会显示: |
Only in目录: |
文件A若使用-N参数,则diff会将文件A与一个空白的文件比较。 |
-p |
若比较的文件为C语言的程序码文件时,显示差异所在的函数名称。 |
-P或--unidirectional-new-file |
与-N类似,但只有当第二个目录包含了一个第一个目录所没有的文件时,才会将这个文件与空白的文件做比较。 |
-q或--brief |
仅显示有无差异,不显示详细的信息。 |
-r或--recursive |
比较子目录中的文件。 |
-s或--report-identical-files |
若没有发现任何差异,仍然显示信息。 |
-S<文件>或--starting-file<文件> |
在比较目录时,从指定的文件开始比较。 |
-t或--expand-tabs |
在输出时,将tab字符展开。 |
-T或--initial-tab |
在每行前面加上tab字符以便对齐。 |
-u,-U<列数>或--unified=<列数> |
以合并的方式来显示文件内容的不同。 |
-v或--version |
显示版本信息。 |
-w或--ignore-all-space |
忽略全部的空格字符。 |
-W<宽度>或--width<宽度> |
在使用-y参数时,指定栏宽。 |
-x<文件名或目录>或--exclude<文件名或目录> |
不比较选项中所指定的文件或目录。 |
-X<文件>或--exclude-from<文件> |
您可以将文件或目录类型存成文本文件,然后在=<文件>中指定此文本文件。 |
-y或--side-by-side |
以并列的方式显示文件的异同之处。 |
--help |
显示帮助。 |
--left-column |
在使用-y参数时,若两个文件某一行内容相同,则仅在左侧的栏位显示该行内容。 |
--suppress-common-lines |
在使用-y参数时,仅显示不同之处。 |
从生成补丁文件,到使用其实现更新软件的目的,为了解整个过程,下面创建两个文件(分别模拟旧软件和新软件),通过对比新旧文件生成补丁文件,最后利用补丁文件更新旧文件:
创建两个文件,执行如下命令
[root@localhost ~]# mkdir test
#建立测试目录
[root@localhost ~]# cd test
#进入测试目录
[root@localhost test]# vi old.txt
our
school
is
lampbrother
#文件old.txt,为了便于比较,将每行分开
[root@localhost test]# vi new.txt
our
school
is
lampbrother
in
Beijing
#文件new.txt
利用 diff 命令,比较两个文件(old.txt 和 new.txt)的不同,并生成补丁文件(txt.patch),执行代码如下:
[root@localhost test]# diff -Naur /root/test/old.txt /root/test/new.txt > txt. patch
#比较两个文件的不同,同时生成txt.patch补丁文件
[root@localhost test]#vi txt.patch
#查看一下这个文件
--/root/test/old.txt 2012-11-23 05:51:14.347954373 +0800
#前一个文件
+ + + /root/test/new.txt 2012-11-23 05:50:05.772988210 +0800
#后一个文件
@@-2, 3+2, 5@@
school
is
lampbrother
+in
+beijing
#后一个文件比前一个文件多两行(用+表示)
利用补丁文件 txt.patch 更新 old.txt 旧文件,实现此步操作需利用 patch 命令,该命令基本格式如下:
[root@localhost test]# patch -pn < 补丁文件
#按照补丁文件进行更新
-pn 选项中,n 为数字(例如 p1、p2、p3 等),pn 表示按照补丁文件中的路径,指定更新文件的位置。
-pn 选项可以这样理解:想要在补丁文件中所记录的目录中取消几个 "/",n 就是几。去掉目录的目的是和当前所在目录匹配。
更新 "old.txt" 文件,命令如下:
[root@localhost test]# patch -p3 < txt.patch
patching file old.txt
#给old.txt文件打补丁
[root@localhost test]# cat old.txt
#查看一下dd.txt文件的内容
our
school
is
lampbrother
in
Beijing
#多出了in Beijing两行
使用补丁文件 txt.patch 对旧文件进行更新,使旧文件和新文件完全相同。
通过上例了解以下两点:
给apache打入补丁
以 apache 为例,通过从官网上下载的补丁文件 "mod_proxy_ftp_CVE-2008-2939.diff",更新 httpd-2.2.9 版本的 apache。
具体更新步骤:
从 apache 官网上下载补丁文件;
复制补丁文件到 apache 源码包解压目录中,执行命令如下:
[root@localhost ~]# cp mod_proxy_ftp_CVE-2008-2939.diff httpd-2.2.9
给旧 apache 打入补丁,具体执行命令如下:
[root@localhost ~]# cd httpd-2.2.9
#进入apache源码目录
[root@localhost httpd-2.2.9]# vi mod_proxy_ftp_CVE-2008-2939.diff
#查看补丁文件
--modules/proxy/mod_proxy_ftp.c (Revision 682869)
+ + + modules/proxy/mod_proxy_ftp.c (Revision 682870)
…省略部分输出…
#查看一下补丁文件中记录的目录,以便一会儿和当前所在目录同步
[root@localhost httpd-2.2.9]# patch - p0 < mod_proxy_ftp_CVE-2008-2939.diff
#打入补丁
当前在 "/root/httpd-2.2.9" 目录中,但补丁文件中记录的目录是 "modules/proxy/mod_proxy_ftp.c",就在当前所在目录中,因此一个 "/" 都不需要去掉,所以是 "-p0"。
重新编译 apache 源码包,执行如下命令:
[root@localhost httpd-2.2.9]# make
安装 apache,执行如下命令:
[root@localhost httpd-2.2.9]# make install
打补丁更新软件的过程比安装软件少了 "./configure" 步骤,且编译时也只是编译变化的位置,编译速度更快。
注意,如果未安装过 httpd-2.2.9,就需要先打入补丁,再依次执行 "./configure"、"make"、
"make install" 命令。
patch 命令不仅可以给就文件打入补丁,还可以执行反操作,即恢复用补丁文件修改过的源文件
例如:
[root@localhost httpd-2.2.9]# patch -R < modjDroxy_ftp_CVE-2008-2939.diff
-R(大写)选项表示还原补丁。