Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3415410
  • 博文数量: 534
  • 博客积分: 11595
  • 博客等级: 上将
  • 技术积分: 5785
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-22 17:00
文章分类

全部博文(534)

文章存档

2015年(4)

2014年(27)

2013年(15)

2012年(38)

2011年(36)

2010年(85)

2009年(63)

2008年(142)

2007年(124)

分类: LINUX

2007-09-28 17:16:44

八、补丁部分

补丁是内核的一个补充或者修改,例如修改某些错误,增加某些功能等。

补丁的体积一般很小,但也有很大的(在后面可以看到),这是它的一个优点,下载一个几十KB的文件总比下载一个动辄几十MB 的内核源代码包要快得多

所以说补丁也不能忽视的。

要学习如何使用补丁,就必须从 diff 命令学起,因为补丁就是通过它来生成的。

1
、我们先给出 diff 命令的主要选项

        a
-e ed 模式

        b
-u unified 模式

        c
-i 忽略大小写

        d
-s 文件相同时报告

        e
-r 递归

        f
-N 如果文件只存在于一方,则当成对方存在同名空文件。

        g
--exclude= 排除匹配该 shell wildcard 的文件或者子目录

        h
--exclude-from= 从指定文件读取 exluce 信息

        i
-b 忽略空格的差异

        j
-B 忽略空行的差异

        k
-I 忽略指定模式的差异

        l
--side-by-side 分列输出格式。


2
diff 的输出格式

diff
5种输出格式,分别是 normaledRCSContextUnified 。这5种各有不同,其中最常用的就是 normal unified 格式,

其中 unified 格式也是内核补丁所采用的格式。它和直观,但所包含的内容也比 ed 格式或者 normal 格式的多,所以体积比较大,

特别是对于一些重大版本的升级更是如此。

下面只介绍 Normal 格式和 Unified 格式,ed 格式输出内容很少,不利于我们的阅读,但执行起来比较快

假设有两个文件 a b,内容如下

CODE:

[bob@mail bob]$ cat -n a
     1  ebc
     2  de
     3  123
     4  ok1
[bob@mail bob]$ cat -n b
     1  de
     2  abc
     3  123
     4  ok
[bob@mail bob]$


下面是 Normal 格式的输出

CODE:

[bob@mail bob]$ diff a b
1d0                                                                                #
注释 :删除文件 a 的第1 ebc 行)
< ebc
2a2                                                                                #
注释 :插入 abc 到新的 a 文件的第2行处 ,也就是 dc → abc → 123 → ok1
> abc
4c4                                                                                #
注释 :把新的 a 文件的第4行(ok1)删除,改为 ok ,并插入到第4行处
< ok1               
---                                                                                                
也就是 dc → abc → 123 → ok
> ok
[bob@mail bob]$


下面是 Unified 格式的输出

CODE:

[bob@mail bob]$ diff -u a b
--- a   2007-09-20 17:23:40.000000000 +0800
+++ b   2007-09-20 17:23:41.000000000 +0800
@@ -1,4 +1,4 @@
-ebc                                                #
注释 :删除 a ebc
de
+abc                                                #
注释 :在 de 后插入 abc         
123
-ok1                                                #
注释 :删除 123 后的 ok1
+ok                                                        #
注释 :插入 ok
[bob@mail bob]$


上面只是把结果输出到 stdout ,你可以通过 IO 重定向把它保存起来。

3
、使用diff 生成补丁

我们需要3个目录 ,分别是

QUOTE:

        /home/bob/old :模拟开发者上的旧版本目录
        /home/bobnew
:模拟开发者上的新版本目录
        /tmp/mine
:这个是我们机器上的目录,将要更新的就是该目录下的文件


下面是生成补丁的过程

CODE:

[bob@mail bob]$ diff -Nru $(pwd)/old/ $(pwd)/new/ > new.patch
[bob@mail bob]$
[bob@mail bob]$ file new.patch
new.patch: 'diff' output text                                                
[bob@mail bob]$


查看补丁文件 new.patch 的内容

CODE:

[bob@mail bob]$cat new.patch
diff -Nru /home/bob/old/a /home/bob/new/a
--- /home/bob/old/a     2007-09-20 23:30:43.000000000 +0800
+++ /home/bob/new/a     2007-09-20 23:30:46.000000000 +0800
@@ -1,6 +1,5 @@
-ebc
de
+abc
123
-ok1
-### tmpline
-
+ok
+# tmpline
diff -Nru /home/bob/old/b /home/bob/new/b
--- /home/bob/old/b     2007-09-21 16:07:28.000000000 +0800
+++ /home/bob/new/b     2007-09-21 16:08:05.000000000 +0800
@@ -1,3 +1,5 @@
-redhat 9
+rehdat 9
RHEL4
Windows
+CentOS
+Slackware
[bob@mail bob]$


上面有多行以 diff -Nru 开头的行,后面是 --- +++ 开头的行,

对每个文件的修改都有这3行,diff -Nru 是给出生成指定文件的补丁的命令,--- 是指旧版本的文件,+++ 是指新版本的文件

可以看到补丁文件实际上就是由多个这样的块组成的。


4
、下面用 new.patch 尝试升级我们的文件

/tmp/mine/  
目录和 /home/bob/old/ 相比,后者就类似于发布该补丁的主机上的目录,前者就是我们想用该补丁升级的内容所在的目录

在打补丁之前需要做一件事,就是先查看补丁文件中的路径结构是否和我们的结构一致,也就是决定 -p 的值。

下面给出一个例子

CODE:

[bob@mail mine]$ head -n3 ../new.patch     
diff -Nru /home/bob/old/a /home/bob/new/a
--- /home/bob/old/a     2007-09-20 23:30:43.000000000 +0800
+++ /home/bob/new/a     2007-09-20 23:30:46.000000000 +0800
[bob@mail mine]$ patch -p4 < ../new.patch --dry-run                        #
注释 :可以看到要指向 /tmp/mine/a,必须去掉前面的4/ ,只剩下 ‘a’ 或者 ‘b’ 就可以
patching file a                                                                                                        
patching file b
[bob@mail mine]$


如果使用了错误的 -p 值会怎样呢?

CODE:

[bob@mail mine]$ patch -p3 < ../new.patch --dry-run                        
can't find file to patch at input line 4                                                                        #
注释 :提示错误路径,因为 /tmp/mine 下没有 old/ 目录
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|diff -Nru /home/bob/old/a /home/bob/new/a
|--- /home/bob/old/a    2007-09-20 23:30:43.000000000 +0800
|+++ /home/bob/new/a    2007-09-20 23:30:46.000000000 +0800
--------------------------
File to patch:
(此处按 CTRL-C
[bob@mail mine]$


:建议在真正打补丁之前,都要用 --dry-run 先测试一番,以免无畏浪费时间

5
、使用 new.patch ”真正升级

[bob@mail mine]$ patch -b -p4 < ../new.patch
patching file a
patching file b
[bob@mail mine]$
[/code]

CODE:

[bob@mail mine]$ ll
total 16
-rw-rw-r--    1 bob      bob            24 Sep 21 16:42 a
-rw-rw-r--    1 bob      bob            28 Sep 21 15:57 a.orig                #
注释 :这就是 -b 的作用,把源文件备份为 xxx.orig
-rw-rw-r--    1 bob      bob            40 Sep 21 16:42 b
-rw-rw-r--    1 bob      bob            23 Sep 21 16:17 b.orig
[bob@mail mine]$


可以看到有 .orig 文件存在,这是 -b 选项所造成的,-b 用于强制备份每个修改过的文件

6
、查看新版本的文件的内容

CODE:

查看新的 a b 文件的内容
[bob@mail mine]$ cat a
de
abc
123
ok
# tmpline
[bob@mail mine]$
[bob@mail mine]$ cat b
rehdat 9
RHEL4
Windows
CentOS
Slackware                                       
[bob@mail mine]$


是否变成了和 /home/bob/new/ 下的 a b 文件一样的内容了呢 ! ^_^

7
、如何撤销一个补丁

如果一个补丁我们打到一半报错了,应该怎么办呢?或者说我们发现该补丁有 bug ,想卸载它呢?

这就要用到 -R 选项了,-R reverse (相反)的意思,顾名思义就是去掉之前打的补丁,回到原来的老样子

CODE:

[bob@mail mine]$ rm -f *.rej
[bob@mail mine]$
[bob@mail mine]$ patch -R -p4 < ../new.patch  
patching file a
patching file b
[bob@mail mine]$
[bob@mail mine]$ cat a
ebc
de
123
ok1
### tmpline

[bob@mail mine]$ cat b
redhat 9
RHEL4
Windows
[bob@mail mine]$


可以看到 a b 文件又变成原来的内容了

8
、重复打补丁会怎样?

假设我们刚刚打了 new.patch ,然后又再打一次会怎样呢?

CODE:

[bob@mail mine]$ patch -b -p4 < ../new.patch
patching file a
Reversed (or previously applied) patch detected!  Assume -R? [n] n
Apply anyway? [n] n
Skipping patch.
1 out of 1 hunk ignored -- saving rejects to file a.rej
patching file b
Reversed (or previously applied) patch detected!  Assume -R? [n] n
Apply anyway? [n] n
Skipping patch.
1 out of 1 hunk ignored -- saving rejects to file b.rej
[bob@mail mine]$ ll
total 24
-rw-rw-r--    1 bob      bob            24 Sep 21 16:42 a
-rw-rw-r--    1 bob      bob            28 Sep 21 15:57 a.orig
-rw-rw-r--    1 bob      bob           116 Sep 21 16:46 a.rej
-rw-rw-r--    1 bob      bob            40 Sep 21 16:42 b
-rw-rw-r--    1 bob      bob            23 Sep 21 16:17 b.orig
-rw-rw-r--    1 bob      bob           121 Sep 21 16:46 b.rej
[bob@mail mine]$


可以看到生成了.rej 文件,一旦 patch 生成了 .rej ,就意味着有某些文件无法正确地被修改。这有可能是你自己改过源文件所致

阅读(1712) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~