目录
1.概述
程序是人设计出来的,总是会有这样那样的问题与漏洞,目前的主流解决方法就是为有问题的程序打补丁,升级新版本。
在Linux系统中diff命令可以为我们生成补丁文件,然后使用patch命令为有问题的程序代码打补丁。
2.使用diff对比单个文件差异
1) 编写两个版本的脚本,一个为v1版本,一个为v2版本。
- [root@proxy ~]# cat test1.sh //v1版本脚本
- hello,i am jjh
today nice- [root@proxy ~]# cat test2.sh //v2版本脚本
- hello,i am ljz
yestday is nice
2) 使用diff命令语法
使用diff命令查看不同版本文件的差异。
- [root@proxy ~]# diff test1.sh test2.sh //查看文件差异
- 1,2c1,2
< hello,i am jjh
< today nice
---
> hello,i am ljz
> yestday is nice- [root@proxy ~]# diff -u test1.sh test2.sh //查看差异,包含头部信息
- --- test1.txt 2020-02-04 11:53:25.390097646 +0800
+++ test2.txt 2020-02-04 11:53:58.261485821 +0800
@@ -1,2 +1,2 @@
-hello,i am jjh #文件1想变成文件2,需要删除两条信息,'-'代表删除
-today nice
+hello,i am ljz #'+' 代表加入列出信息
+yestday is nice
diff制作补丁文件的原理:告诉我们怎么修改第一个文件后能得到第二个文件。
这样如果第一个版本的脚本有漏洞,我们不需要将整个脚本都替换,仅需要修改有问题的一小部分代码即可,diff刚好可以满足这个需求!
像Linux内核这样的大块头,一旦发现有一个小漏洞,我们不可能把整个内核都重新下载,全部替换一遍,而仅需要更新有问题的那一小部分代码即可!
3.diff命令常用选项:
-u 输出统一内容的头部信息(打补丁使用),计算机知道是哪个文件需要修改
-r 递归对比目录中的所有资源(可以对比目录)
-a 所有文件视为文本(包括二进制程序)
-N 无文件视为空文件(空文件怎么变成第二个文件)
-N选项备注说明:
A目录下没有txt文件,B目录下有txt文件
diff比较两个目录时,默认会提示txt仅在B目录有(无法对比差异,修复文件)
diff比较时使用N选项,则diff会拿B下的txt与A下的空文件对比,补丁信息会明确说明如何从空文件修改后变成txt文件,打补丁即可成功!
4.使用patch命令对单文件代码打补丁
1)准备实验环境
- [root@proxy ~]# cd demo
- [root@proxy demo]# vim test1.sh
- #!/bin/bash
- echo "hello world"
- echo "test"
- [root@proxy demo]# vim test2.sh
- #!/bin/bash
- echo "hello the world"
- echo "test file"
2) 生成补丁文件
- [root@proxy demo]# diff -u test1.sh test2.sh > test.patch
3)使用patch命令打补丁
在代码相同目录下为代码打补丁
- [root@proxy demo]# yum -y install patch
- [root@proxy demo]# patch -p0 < test.patch //打补丁
- patching file test1.sh
- //patch -pnum(其中num为数字,指定删除补丁文件中多少层路径前缀)
- //如原始路径为/usr/howard/src/blurfl/blurfl.c
- //-p0则整个路径不变,相当于当前路径
4)反向修复:卸载补丁,还原版本
- //-R(reverse)反向修复,-E修复后如果文件为空,则删除该文件
- [root@proxy demo]# patch -RE < test.patch //还原旧版本,反向修复
5.对比目录中所有文件的差异
1) 准备两个目录
创建两个目录,人为的制造差异
- [root@proxy ~]# mkdir demo #创建父目录demo
- [root@proxy ~]# cd demo
- [root@proxy demo]# mkdir {source1,source2} #创建子目录source1和source2
- [root@proxy demo]# echo "hello world" > source1/test.sh #在source1下创建一个子文件
- [root@proxy demo]# ls source1/ #source1目录下1个文件
- test.sh
- [root@proxy demo]# echo "hello the world" > source2/test.sh #在source2下创建一个子文件
- [root@proxy demo]# echo "test" > source2/tmp.txt #在source2下创建一个子文件
- [root@proxy demo]# tree source2/ //source1目录下3个文件
- test.sh tmp.txt
2)制作补丁文件
- [root@proxy demo]# diff -u source1/ source2/
- //仅对比了文本文件test.sh;二进制文件、tmp都没有对比差异,仅提示,因为没有-a和-N选项
- [root@proxy demo]# diff -Nu source1/ source2/
- //对比了test.sh,并且使用source2目录的tmp.txt与source1的空文件对比差异。
- [root@proxy demo]# diff -Nua source1/ source2/
- //对比了test.sh、tmp.txt、find(程序)。
3)使用patch命令对目录下的所有代码打补丁
使用前面创建的source1和source2目录下的代码为素材,生成补丁文件
- [root@proxy ~]# cd demo
- [root@proxy demo]# diff -Nuar source1/ source2/ > source.patch
4)使用patch命令为代码打补丁
- [root@proxy demo]# ls
- source1 source2 source.patch
- [root@proxy demo]# cat source.patch //对比的文件有路径信息
- --- source1/test.sh 2018-02-07 22:51:33.034879417 +0800
- +++ source2/test.sh 2018-02-07 22:47:32.531754268 +0800
- @@ -1 +1 @@
- -hello world
- +hello the world
- [root@proxy demo]# cd source1
- [root@proxy source1]# patch -p1 < ../source.patch #由于进入到了source1目录,这里的-p需要写1,路径前缀需要追加一层