a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 86|回复: 1

[LPI认证] Linux认证:Linux中patch文件的使用

[复制链接]
发表于 2012-8-4 12:13:19 | 显示全部楼层 |阅读模式
因为在u-boot移植过程中,有几处通用文件要修改,如果每次都要手动修改就太麻烦了。制作补丁可以解决这个问题。   学习资料的收集比较简单,方法一类似于这种初级问题网上资料非常丰富,google或者baidu搜索一下,然后选择有价值的资料,方法二是阅读man在线文档。完成收集工作,当然最终要在自己的Linux上作实验,比较总结,消化吸收为自己的东西。要除去这么一种错误思想:一定要学全。要知道,一次学全是不可能的,只能先学习最为常用的,在以后不断实践的过程中逐步的丰富,最终达到比较高的水平。把握的原则是:日有所学,学以致用,用以促学。
; V" `. d6 k% e) U/ M1 J5 S  首先介绍一下diff和patch。在这里不会把man在线文档上所有的选项都介绍一下,那样也没有必要。在99%的时间里,我们只会用到几个选项。所以必须学会这几个选项。/ K: C1 q7 @+ ]7 v- U) }- c1 i0 \& j. W
  1、diff" T* y( _6 ^& a; |' P( Y$ l; N7 L
  --------------------- k9 a2 }8 N  s7 e2 H- o3 J$ F
  NAME
1 S$ Z8 F+ f9 J+ T  diff - find differences between two files5 c) W" \+ c  X% o5 s! P
  SYNOPSIS! @% U& r  G+ Y# R' \. [% H
  diff [options] from-file to-file7 O1 d/ T% h- q1 @, o
  --------------------: U% r) m( _: N7 u7 G; N
  简单的说,diff的功能就是用来比较两个文件的不同,然后记录下来,也就是所谓的diff补丁。语法格式:diff 【选项】 源文件(夹) 目的文件(夹),就是要给源文件(夹)打个补丁,使之变成目的文件(夹),术语也就是“升级”。下面介绍三个最为常用选项:
$ g+ K- V; C+ J3 O( Q! h% `+ J  -r 是一个递归选项,设置了这个选项,diff会将两个不同版本源代码目录中的所有对应文件全部都进行一次比较,包括子目录文件。
; A# T- V, b( s7 x" H, B  -N 选项确保补丁文件将正确地处理已经创建或删除文件的情况。2 T% N3 U5 }4 |) s$ R. a. M( _
  -u 选项以统一格式创建补丁文件,这种格式比缺省格式更紧凑些。
/ J. z# u( `% @$ n9 e  2、patch
$ a# n/ r, J9 d9 ^+ w  ------------------: N2 x$ B( r) I& D
  NAME4 X) r# R* f4 J+ {5 A
  patch - apply a diff file to an original
. ~" S  g' @% T( Y% ?* Q/ v  SYNOPSIS
5 m+ k0 c4 k# ~* U$ o  patch [options] [originalfile [patchfile]]. m" i+ R$ V9 c( c
  but usually just
& C4 N7 _" d% v+ W9 x9 k  patch -pnum
& I) X, Y& C( e/ t  ------------------
2 g. U; z, ]- @7 U  简单的说,patch就是利用diff制作的补丁来实现源文件(夹)和目的文件(夹)的转换。这样说就意味着你可以有源文件(夹)――>目的文件(夹),也可以目的文件(夹)――>源文件(夹)。下面介绍几个最常用选项:- \4 Q0 T% u% z& u4 e
  -p0 选项要从当前目录查找目的文件(夹)
+ u* g6 x/ V$ B3 K0 \2 |2 _# _  -p1 选项要忽略掉第一层目录,从当前目录开始查找。
, J6 X9 f& `; @- o# f. t  ************************************************************
$ w, u1 D3 G1 z4 ^  i+ f  在这里以实例说明:0 M5 f, L9 Y( b4 J
  --- old/modules/pcitable       Mon Sep 27 11:03:56 1999
2 ?6 n: [& U5 r& B. A  +++ new/modules/pcitable       Tue Dec 19 20:05:41 2000
/ f6 M4 p$ }* \6 u/ g  k8 M" s3 _  如果使用参数-p0,那就表示从当前目录找一个叫做old的文件夹,在它下面寻找modules下的pcitable文件来执行patch操作。
3 o3 @9 s5 B+ D& f/ t5 t  如果使用参数-p1,那就表示忽略第一层目录(即不管old),从当前目录寻找modules的文件夹,在它下面找pcitable。这样的前提是当前目录必须为modules所在的目录。而diff补丁文件则可以在任意位置,只要指明了diff补丁文件的路径就可以了。当然,可以用相对路径,也可以用绝对路径。不过我一般习惯用相对路径。
' f8 B% W& f, }1 z8 |2 j8 b* r  ************************************************************
, f" Z3 g6 v' L8 T9 C% S6 g  -E  选项说明如果发现了空文件,那么就删除它+ X* O: r) R6 t' \! \( i, e
  -R  选项说明在补丁文件中的“新”文件和“旧”文件现在要调换过来了(实际上就是给新版本打补丁,让它变成老版本)
+ S9 k8 S- |) B  下面结合具体实例来分析和解决,分为两种类型:为单个文件打补丁和为文件夹内的多个文件打补丁。; ]8 @" u- s7 e! l5 r
  环境:在RedHat 9.0下面以armlinux用户登陆。' [- F, f7 ~9 o4 ^" \% M
  目录树如下:9 q0 [8 b/ @9 A
  |-- bootloader8 [. f3 }8 M# V* k# O$ r
  |-- debug
- n2 j: m7 q$ v, `' p/ w  |-- images, r1 W& g5 H9 D5 X7 W! e/ Q
  |-- kernel! c1 I; q( w* J3 s: i4 Z
  |-- program1 r% R2 k& k5 ^$ F! Q
  |-- rootfiles
% n1 F" ^: b5 {  |-- software9 E; g- T3 X" b* T
  |-- source
' z6 q" s$ ?) p+ B5 R7 e' I1 S  |-- sysapps6 d6 d: ~- ~( L
  |-- tmp" Y; L5 N5 M. C: K' T  Z/ q
  `-- tools& Y$ W' v# z4 L: t, n
  下面在program文件夹下面建立patch文件夹作为实验用,然后进入patch文件夹。
0 J: q" E4 A! B' A0 o6 {  一、为单个文件进行补丁操作
# J. b6 }, a3 ?3 e7 I% X- ^  1、建立测试文件test0、test1+ d* s, j% x/ S; {/ O1 x$ d2 n0 d
  [armlinux@lqm patch]$ cat  >>test0 1111119 o- i4 g# w6 k; x* C1 w
  > 111111* X$ @/ W; b5 l' `/ y
  > EOF% k# t7 [3 `  U. z/ a3 C4 B3 `
  [armlinux@lqm patch]$ more test0
. T( Z  x8 j$ T  111111, N' c4 n$ K' y3 H6 X6 D9 R
  111111
. o1 s/ P" N+ D4 |6 k. b  111111
6 p7 D2 x9 E8 p% b5 A2 U  [armlinux@lqm patch]$ cat >>test1 111111
6 g6 H0 i; Q4 d4 X" \/ Z  > 222222
& j7 r, r: n- w8 ?6 ~. w  ?  > 111111
( `- N: u0 e3 v3 @1 }% A  J! ]  > EOF
6 u$ H; b$ e/ e2 r  [armlinux@lqm patch]$ more test1
5 h; d# |; J% e/ l$ o/ \/ H! W  222222
: ^  J. g3 g6 F! J9 U  111111
0 Q+ H' N; o- f4 ?; G, e  111111
% c) F8 V# M5 w+ G8 |: J8 A% ~  2、使用diff创建补丁test1.patch9 S+ Q( p, |) R, |) f1 n4 E
  [armlinux@lqm patch]$ diff -uN test0 test1 > test1.patch
4 j: {0 m* ^+ K4 ?  【注:因为单个文件,所以不需要-r选项。选项顺序没有关系,即可以是-uN,也可以是-Nu。】
* @% q! `$ U( s6 s  [armlinux@lqm patch]$ ls
% F( |6 O0 ^4 q$ @+ v9 d4 [3 o4 x' M  test0  test1  test1.patch
$ P5 b/ `8 @; h6 @  [armlinux@lqm patch]$ more test1.patch
1 j4 A2 H1 S: d; A( m$ d  ************************************************************
2 m, f- K* x) ]4 J1 J% b5 _, O  patch文件的结构
3 g* b6 g9 `% e  补丁头6 Z* M+ V7 d2 f# R
  补丁头是分别由---/+++开头的两行,用来表示要打补丁的文件。---开头表示旧文件,+++开头表示新文件。
. w5 |1 S4 e/ H! k$ a: n  一个补丁文件中的多个补丁
% M  @* I9 M% ?  P' |* y+ S  一个补丁文件中可能包含以---/+++开头的很多节,每一节用来打一个补丁。所以在一个补丁文件中可以包含好多个补丁。" E) G$ y" J6 B! v' F4 X
  块
8 g: P/ S% i' l8 v1 f  u, @2 ?  块是补丁中要修改的地方。它通常由一部分不用修改的东西开始和结束。他们只是用来表示要修改的位置。他们通常以@@开始,结束于另一个块的开始或者一个新的补丁头。
- ^: M6 v# {: c& P  块的缩进
1 r: D0 y% r* v9 U& T% Q7 p  块会缩进一列,而这一列是用来表示这一行是要增加还是要删除的。# H- M' ~/ L0 M% ^( Q1 M3 w
  块的第一列
: n! q8 y8 ]$ I  V9 B$ x! [  +号表示这一行是要加上的。1 `2 |6 [* K: Z+ Z9 H
  -号表示这一行是要删除的。
: b7 e$ e6 {7 _1 `" p$ e) x  没有加号也没有减号表示这里只是引用的而不需要修改。
5 _1 m  {8 H! [1 e  ************************************************************' I8 r5 Y& r7 p; S3 Y1 ~' o; H
  ***diff命令会在补丁文件中记录这两个文件的首次创建时间,如下***
8 n9 l( A1 K" B) M* R# h  --- test0       2006-08-18 09:12:01.000000000 +0800& E5 y& P, J, [, p  ^8 B
  +++ test1       2006-08-18 09:13:09.000000000 +0800
- u. C% I# l3 H' m4 J. x. j  @@ -1,3 +1,4 @@% l# s. V% x9 X9 F
  +222222
* K  B7 Y7 D5 v$ e3 z, z  111111
8 h6 O4 a+ @# o/ O  -111111
: [8 A3 F) N7 ]  +222222
3 q* `- Z, W& V& S3 g7 Z/ }. O  111111. \/ D, ^1 w4 T& {2 K% d  K
  [armlinux@lqm patch]$ patch -p0 < test1.patch4 R" T" y1 O  i9 c9 E
  patching file test0www.Examw.com
* V7 m2 p% Y0 s- Y# `  [armlinux@lqm patch]$ ls
8 O: Z& o/ N8 r  font>test0  test1  test1.patch7 G& U3 C% C2 ]
  [armlinux@lqm patch]$ cat test0
4 y; R3 f+ r  O$ |  222222) h( P' {+ L; w  v: Z
  1111111 E/ N# X$ ~# }( l/ D
  222222" H( a% U8 \% H+ t
  111111
回复

使用道具 举报

 楼主| 发表于 2012-8-4 12:13:20 | 显示全部楼层

Linux认证:Linux中patch文件的使用

 3、可以去除补丁,恢复旧版本   [armlinux@lqm patch]$ patch -RE -p0 < test1.patch: K. M* x# {0 t, x  y  w" a& |3 b
  patching file test0! V7 r! ~, R1 r) R' p( K
  [armlinux@lqm patch]$ ls: [% O( K0 {, N) J3 H
  test0  test1  test1.patch; S2 t- i  t/ O, Q. l7 X! e$ H
  [armlinux@lqm patch]$ cat test08 a2 d! D: y0 h; w% _+ X
  1111112 {& L& h" X4 c& {
  111111
8 o2 l% o. U1 d9 m0 }) T7 i( k/ w  111111
% c! @: Z! m+ ^! Y. z* G% ^+ M  二、为多个文件进行补丁操作  L) m9 e+ I# H* K& K- `
  1、创建测试文件夹
- H+ O: v+ y0 W  [armlinux@lqm patch]$ mkdir prj0
) X5 E5 [  ^2 T6 w: N. p$ Z  [armlinux@lqm patch]$ cp test0 prj0
$ {. L4 K! j) N+ z4 P0 @" [  [armlinux@lqm patch]$ ls
6 s/ Z( y, v, T& `7 F* B6 r  prj0  test0  test1  test1.patch
/ L$ h' H- o3 _0 w: [1 J; \  [armlinux@lqm patch]$ cd prj0/
3 W( Z) `8 R+ m1 D5 ~  [armlinux@lqm prj0]$ ls/ _3 M3 D% ~  F8 f" D
  test0
0 G% z9 v. U" Y1 O* }  [armlinux@lqm prj0]$ cat >>prj0name prj0/prj0name7 f7 j9 ~: C' C3 z& e
  > --------
' ~/ U2 F4 }. r) f  > EOF# D  `" M! Q7 \9 m; J- U
  [armlinux@lqm prj0]$ ls4 @* g0 A# C7 _, G
  prj0name  test0
+ a% D) |& I5 U' r+ |% _0 p3 V  [armlinux@lqm prj0]$ cat prj0name- n, A- d7 b* }2 s% o4 T
  --------
. j% X: I# n" g9 I  prj0/prj0name$ F( [/ [2 I/ W& H) `( g- _
  --------
) ^4 D9 N$ A3 {6 K7 Q  [armlinux@lqm prj0]$ cd ..
, g% {9 {1 g- \5 x8 g8 q3 T  [armlinux@lqm patch]$ mkdir prj1: z/ u; ?; B4 U: ~1 X: o/ Y) V6 i* u
  [armlinux@lqm patch]$ cp test1 prj1
; O4 R/ f# ]; I) {' V+ q9 d  [armlinux@lqm patch]$ cd prj1! H% ~  V  `& d
  [armlinux@lqm prj1]$ cat >>prj1name prj1/prj1name$ B7 S7 m4 q* d/ I! b7 }+ h
  > ---------
& `7 u: o# Z6 d9 h  > EOF
" o! m# W* R- g! d) f' p& G% f) O2 c  [armlinux@lqm prj1]$ cat prj1name
/ `2 p7 i9 M& w# t, s4 [  ---------% y+ v/ h! C- `3 l
  prj1/prj1name9 Z1 o; ^+ K5 w9 r' z
  ---------; f$ N* c+ C2 v. t
  [armlinux@lqm prj1]$ cd ..
; |% e) n/ N4 |8 k& m" A4 w  2、创建补丁0 I7 _( L  u: c& ^4 @! c
  [armlinux@lqm patch]$ diff -uNr prj0 prj1 > prj1.patch+ z" C, R1 w! H9 S# j( n. ~
  [armlinux@lqm patch]$ more prj1.patch0 g- Y% Y4 [0 g; M0 H
  diff -uNr prj0/prj0name prj1/prj0name
  f- [3 N; W6 l! D  --- prj0/prj0name       2006-08-18 09:25:11.000000000 +08008 K: F7 l3 f& C* a8 l
  +++ prj1/
: G/ ]! z2 F: U, j" i  prj0name       1970-01-01 08:00:00.000000000 +0800: T+ {1 m8 ?' h3 i1 g, i! u3 S- Z& m
  @@ -1,3 +0,0 @@! ]( l1 w$ T0 b4 @
  ---------2 l/ z  t+ t2 P
  -prj0/prj0name+ Y6 E' i; a  S3 m" d
  ---------
5 }# V. g, A* c5 ~- N1 `  j  diff -uNr prj0/prj1name prj1/prj1name9 ?* ?* X3 l" E% H0 E* s4 f! k
  --- prj0/prj1name       1970-01-01 08:00:00.000000000 +0800
: j! ]% |' h& P$ [  +++ prj1/prj1name       2006-08-18 09:26:36.000000000 +0800# v4 L. k9 `' ~* H; s  H- g" B
  @@ -0,0 +1,3 @@) i, K$ k! x% Y3 E/ B
  +---------
# \- Q# C! @' M+ m9 v  _/ S! B) X  +prj1/prj1name
0 A9 a: I. h5 |  +---------
# \" o0 S* i0 X  diff -uNr prj0/test0 prj1/test0
* R) \6 }$ B5 J4 G# h  --- prj0/test0  2006-08-18 09:23:53.000000000 +0800
5 ]2 X* `# z+ E! k! E7 ]8 H0 C  +++ prj1/test0  1970-01-01 08:00:00.000000000 +0800
* e' J" i* X- s  @@ -1,3 +0,0 @@
8 G0 l& F3 |& M# v  -111111& _1 x, r: N9 m& x3 f
  -111111# e0 r, Q4 ~  s1 N0 ^  T
  -111111
- j7 _9 a  w+ ^0 Z; I( y: w  diff -uNr prj0/test1 prj1/test1( T1 n1 u( x' U6 A3 U
  --- prj0/test1  1970-01-01 08:00:00.000000000 +0800
$ Y  B0 d9 C; _3 B4 e. ]) {  +++ prj1/test1  2006-08-18 09:26:00.000000000 +0800
! e0 o1 C) m# _' Y+ K( d$ Z# a  @@ -0,0 +1,4 @@
4 M2 i7 Y$ x$ z; }7 _. k3 m* q4 T  +222222
: S1 X; Q! i+ B2 h  +111111* m5 {4 w+ s+ w( M8 `6 Y
  +222222
. y; I% }& N  P& j. U; N" J; S  I  +1111118 {; W- P, M8 P$ F( x0 `
  [armlinux@lqm patch]$ ls6 f- @3 I/ q0 H7 t* c
  prj0  prj1  prj1.patch  test0  test1  test1.patch: p. C3 b: N7 }1 o* ^$ `
  [armlinux@lqm patch]$ cp prj1.patch ./prj0. g5 ^, N- N, I$ }- r' X/ r) K' u
  [armlinux@lqm patch]$ cd prj0
/ ^5 `/ R+ n: d  [armlinux@lqm prj0]$ patch -p1 < prj1.patch/ N* i6 {; _+ `* f, M
  patching file prj0name
  x- c/ m3 D. o$ r  patching file prj1name
( ~9 Z7 X6 t# Z7 {- t% O. ?7 I  patching file test0* }0 }5 q# i% F, H0 f6 n8 O3 w
  patching file test1+ G! ]2 W" b! a7 q3 T
  [armlinux@lqm prj0]$ ls
. B7 Z& ~. i, w' o! v  prj1name  prj1.patch  test1, M( d1 X; l6 d  K: m( o
  [armlinux@lqm prj0]$ patch -R -p1 < prj1.patch
& a+ D9 D$ U' F9 }$ _8 U) `  patching file prj0name7 c8 s6 U2 r; t7 p" y( E$ @. K
  patching file prj1name; F$ g, p0 L. D3 }5 Q5 n* o% a$ |' X$ K
  patching file test0
; l) F0 }5 \2 p" q6 v7 G2 i1 {( @  patching file test1
- b2 ~( m1 I+ x) h: I, P) E  [armlinux@lqm prj0]$ ls5 ~! o* ?( C" _% H
  prj0name  prj1.patch  test07 H+ t0 Y- \9 r& n7 \' j: A
  -------------------) k! `% F9 d" r7 {2 X* m& F: t$ J1 j
  总结一下:; R/ R; K& e% y! R
  单个文件
( t# z) g& H) p3 J( n  diff –uN  from-file  to-file  >to-file.patch
& P3 |* c( A: j) ^, f  patch –p0 < to-file.p5 Z+ @  B7 P  M9 e! F, D: Y6 f
  atch
. f3 c* _2 A$ s& ]  patch –RE –p0 < to-file.patch- Z6 m+ j5 u+ x$ {0 d$ b% t
  多个文件! w' D! v  X  u9 L2 |
  diff –uNr  from-docu  to-docu  >to-docu.patch# W& L6 v6 U7 {: B; Z* R" W
  patch –p1 < to-docu.patch
+ H3 e3 B/ F9 q2 B- [$ x" W  patch –R –p1 reject
0 ]2 W& O# E8 P  然后可以查看reject的内容了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-5-15 14:23 , Processed in 0.238115 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表