diff 与 patch 命令
2017-02-09 by dongnan
问题描述
某台服务器系统为 centos 7.3 amd64
编译安装 libiconv-1.14
报错,提示以下错误信息:
In file included from progname.c:26:0:
./stdio.h:1010:1: error: ‘gets’ undeclared here (not in a function)
_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
解决方法参考:http://www.rootop.org/pages/3532.html
目标
减少人工操作(编辑 libiconv-1.14/srclib/stdio.h
),使用 diff & patch
命令制作并应用补丁。
步骤
对比两个文件
diff new.h libiconv-1.14/srclib/stdio.h
1010d1009
< #if defined(__GLIBC__) && !defined(__UCLIBC__) && !__GLIBC_PREREQ(2, 16)
1012d1010
< #endif
创建 patch 文件
diff -uN libiconv-1.14/srclib/stdio.h new.h > diff.patch
# patch 文件内容
cat diff.patch
--- libiconv-1.14/srclib/stdio.h 2017-02-07 11:59:17.730000000 +0800
+++ new.h 2017-02-07 12:57:30.218000000 +0800
@@ -1007,8 +1007,10 @@
/* It is very rare that the developer ever has full control of stdin,
so any use of gets warrants an unconditional warning. Assume it is
always declared, since it is required by C89. */
+#if defined(__GLIBC__) && !defined(__UCLIBC__) && !__GLIBC_PREREQ(2, 16)
_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
#endif
+#endif
#if 0 || 0
使用 patch 命令 打补丁
patch -p2 < diff.patch libiconv-1.14/srclib/stdio.h
注意,p2
数字2
验证
对比文件
diff new.h libiconv-1.14/srclib/stdio.h
输出空,表示打补丁成功(文件相同)
如果反悔了,还可以去除补丁 使用 -R参数即可
patch -R -p2 < diff.patch libiconv-1.14/srclib/stdio.h
patching file libiconv-1.14/srclib/stdio.h
再次对比文件,两个文件恢复到初始状态
diff new.h libiconv-1.14/srclib/stdio.h
1010d1009
< #if defined(__GLIBC__) && !defined(__UCLIBC__) && !__GLIBC_PREREQ(2, 16)
1012d1010
< #endif
帮助
diff 命令
简单的说,diff
的功能就是用来比较两个文件/夹的不同,然后记录下来,也就是所谓的diff
补丁。
语法:diff 【选项】 源文件/夹(旧) 目的文件/夹(新),就是要给源文件(夹)打个补丁,使之变成目的文件(夹)。
-r ,是一个递归选项,设置了这个选项,diff会将两个不同版本源代码目录中的所有对应文件全部都进行一次比较,包括子目录文件。
-N ,选项确保补丁文件将正确地处理已经创建或删除文件的情况。
-u ,选项以统一格式创建补丁文件,这种格式比缺省格式更紧凑些。
一般 -uN 是一直使用的参数,而 -r 如果是含子目录就使用,不含则不使用,参考上面的示例。
补丁文件的结构
补丁头
补丁头是分别由 ---/+++开头的两行,用来表示要打补丁的文件;
--- 开头表示旧文件;
+++ 开头表示新文件。
一个补丁文件中可能包含以 ---/+++开头的很多节,每一节用来打一个补丁。所以在一个补丁文件中可以包含好多个补丁。
--- libiconv-1.14/srclib/stdio.h 2017-02-07 11:59:17.730000000 +0800
+++ new.h 2017-02-07 12:57:30.218000000 +0800
补丁块
块是补丁中要修改的地方。它通常由一部分不用修改的东西开始和结束。
他们只是用来表示要修改的位置。他们通常以@@
开始,结束于另一个块的开始或者一个新的补丁头。
块会缩进一列,这一列是用来表示这一行是要增加还是要删除的。
+号表示这一行是要加上的。
-号表示这一行是要删除的。
没有加号也没有减号表示这里只是引用的而不需要修改。
patch 命令
可以理解,patch
就是利用diff
制作的补丁来实现源文件(夹)和目的文件(夹)的转换。
常用选项:
-pnum ,是指查找patch文件中指定的文件时,忽略前 num个目录,一个"/"为一层。
-R ,选项说明在补丁文件中的"新"文件和"旧"文件现在要调换过来了。
-E ,选项说明如果发现了空文件,那么就删除它。