diff 与 patch 的使用
2018-06-03 11:21
459 查看
摘要
在 Linux 的日常使用中,我们经常需要修改一些配置文件,然而在软件升级以后,经常会面临配置更新后与原配置部分不兼容的问题(当然我们更多的可能是来制作软件升级的补丁)。在这种情况下我们通常有两种选择:对比现有配置,手动在新配置文件中改动
利用
sed、
awk等工具配合改动
采用
diff与
patch制作增量补丁的方式改动
本文主要通过一个升级
awesome配置的例子,对第三种方法进行介绍和讲解。
diff 介绍
diff是一个文件比较工具,可以逐行比较两个文件的不同,其中它有三种输出方式,分别是
normal,
context以及
unified。区别如下:
normal方式为默认输出方式,不需要加任何参数
context相较于
normal模式的简单输出,
contetx模式会输出修改过部分的上下文,默认是前后 3 行。使用参数
-c
unified合并上下文模式则为新的上下文输出模式,同样为前后 3 行,只不过把上下文合并了显示了。使用参数
-u
注:本文主要介绍
unified模式
其他常用参数:
-r递归处理目录
-N将缺失的文件当作空白文件处理
diff 语法与文件格式
先来看一个简单的例子:diff [options] old new
$ cat test1 linuxlinuxlinuxlinux
此时输入$ cat test2locezlinuxlocezlinux
diff -urN test1 test2会输出以下信息:
先看前面 2 行,这两行为文件的基本信息,--- test1 2018-05-12 18:39:41.508375114 +0800+++ test2 2018-05-12 18:41:00.124031736 +0800@@ -1,4 +1,4 @@+locez linux-linux-linux+locez linux
---开头为改变前的文件,
+++开头为更新后的文件。
第三行为上下文描述块,其中--- test1 2018-05-12 18:39:41.508375114 +0800+++ test2 2018-05-12 18:41:00.124031736 +0800
-1,4为旧文件的 4 行上下文,
+1,4为新文件的:
而具体到块里面的内容,前面有@@ -1,4 +1,4 @@
-号的则为删除,有
+号为新增,不带符号则未做改变,仅仅是上下文输出。
patch 介绍
patch是一个可以将
diff生成的补丁应用到源文件,生成一个打过补丁版本的文件。语法:
常用参数:patch [oiption] [originalfile [patchfile]]
-i指定补丁文件
-pNum在
diff生成的补丁中,第一二行是文件信息,其中文件名是可以包含路径的,例如
--- /tmp/test1 2018-05-12 18:39:41.508375114 +0800其中
-p0代表完整的路径
/tmp/test1,而
-p1则指
tmp/test1,
-pN依此类推
-E删除应用补丁后为空文件的文件
-o输出到一个文件而不是直接覆盖文件
应用
awesome 桌面 3.5 与 4.0 之间的升级是不兼容的,所以在升级完 4.0 以后,awesome 桌面部分功能无法使用,因此需要迁移到新配置,接下来则应用diff与
patch实现迁移,当然你也可以单纯使用
diff找出不同,然后手动修改新配置。
现在有以下几个文件:
rc.lua.3.53.5 版本的默认配置文件,未修改
rc.lua.myconfig基于 3.5 版本的个人配置文件
rc.lua.4.24.2 新默认配置,未修改
思路为利用
diff提取出个人配置与 3.5 默认配置文件的增量补丁,然后把补丁应用在 4.2 的文件上实现迁移。
制作补丁
$ diff -urN rc.lua.3.5 rc.lua.myconfig > mypatch.patch
应用补丁
显然应用没有完全成功,其中在 38 行以及 55 行应用失败,并记录在$ patch rc.lua.4.2 -i mypatch.patch -o rc.luapatching file rc.lua (read from rc.lua.4.2)Hunk #1 FAILED at 38.Hunk #2 FAILED at 55.Hunk #3 succeeded at 101 with fuzz 1 (offset 5 lines).Hunk #4 succeeded at 276 with fuzz 2 (offset 29 lines).2 out of 4 hunks FAILED -- saving rejects to file rc.lua.rej
rc.lua.rej里。
这里是主题,终端,以及常用布局的个人设置。$ cat rc.lua.rej --- rc.lua.3.5 2018-05-12 19:15:54.922286085 +0800+++ rc.lua.myconfig 2018-05-12 19:13:35.057911463 +0800@@ -38,10 +38,10 @@ -- {{{ Variable definitions -- Themes define colours, icons, font and wallpapers.-beautiful.init("@AWESOME_THEMES_PATH@/default/theme.lua")+beautiful.init("~/.config/awesome/default/theme.lua") -- This is used later as the default terminal and editor to run.-terminal = "xterm"+terminal = "xfce4-terminal" editor = os.getenv("EDITOR") or "nano" editor_cmd = terminal .. " -e " .. editor@@ -55,18 +55,18 @@ -- Table of layouts to cover with awful.layout.inc, order matters. local layouts = {- awful.layout.suit.floating,- awful.layout.suit.tile,- awful.layout.suit.tile.left,- awful.layout.suit.tile.bottom,- awful.layout.suit.tile.top,+-- awful.layout.suit.floating,+-- awful.layout.suit.tile,+-- awful.layout.suit.tile.left,+-- awful.layout.suit.tile.bottom,+-- awful.layout.suit.tile.top, awful.layout.suit.fair, awful.layout.suit.fair.horizontal, awful.layout.suit.spiral, awful.layout.suit.spiral.dwindle, awful.layout.suit.max, awful.layout.suit.max.fullscreen,- awful.layout.suit.magnifier+-- awful.layout.suit.magnifier } -- }}}
修正补丁
再次通过对比补丁文件与 4.2 文件,发现 38 行区块是要删除的东西不匹配,而 55 行区块则是上下文与要删除的内容均不匹配,导致不能应用补丁,于是手动修改补丁$ vim mypatch.patch
输出省略显示,有兴趣的读者可以仔细与--- rc.lua.3.5 2018-05-12 19:15:54.922286085 +0800+++ rc.lua.myconfig 2018-05-12 19:13:35.057911463 +0800@@ -38,10 +38,10 @@ -- {{{ Variable definitions -- Themes define colours, icons, font and wallpapers.-beautiful.init(gears.filesystem.get_themes_dir() .. "default/theme.lua")+beautiful.init("~/.config/awesome/default/theme.lua") -- This is used later as the default terminal and editor to run.-terminal = "xterm"+terminal = "xfce4-terminal" editor = os.getenv("EDITOR") or "nano" editor_cmd = terminal .. " -e " .. editor@@ -55,18 +55,18 @@ -- Table of layouts to cover with awful.layout.inc, order matters. awful.layout.layouts = {- awful.layout.suit.floating,- awful.layout.suit.tile,- awful.layout.suit.tile.left,- awful.layout.suit.tile.bottom,- awful.layout.suit.tile.top,+-- awful.layout.suit.floating,+-- awful.layout.suit.tile,+-- awful.layout.suit.tile.left,+-- awful.layout.suit.tile.bottom,+-- awful.layout.suit.tile.top, awful.layout.suit.fair, awful.layout.suit.fair.horizontal, awful.layout.suit.spiral, awful.layout.suit.spiral.dwindle, awful.layout.suit.max, awful.layout.suit.max.fullscreen,- awful.layout.suit.magnifier,+-- awful.layout.suit.magnifier, awful.layout.suit.corner.nw, -- awful.layout.suit.corner.ne, -- awful.layout.suit.corner.sw,........
rc.lua.rej文件对比,看看笔者是怎样改的。
再次应用补丁
$ patch rc.lua.4.2 -i mypatch.patch -o rc.luapatching file rc.lua (read from rc.lua.4.2)Hunk #1 succeeded at 41 (offset 3 lines).Hunk #2 succeeded at 57 with fuzz 2 (offset 2 lines).Hunk #3 succeeded at 101 with fuzz 1 (offset 5 lines).Hunk #4 succeeded at 276 with fuzz 2 (offset 29 lines).$ cp rc.lua ~/.config/awesome/rc.lua ### 打完补丁直接使用
总结
diff与
patch配合使用,能当增量备份,而且还可以将补丁分发给他人使用,而且在日常的软件包打补丁也具有重要的意义,特别是内核补丁或者一些驱动补丁,打补丁遇到错误时候可以尝试自己修改,已满足自身特殊要求,修改的时候一定要抓住 2 个非常重要的要素:
要修改的内容是否匹配?特别是要删除的
上下文是否满足,特别是距离要修改的地方前后一行,以及上下文的行数是否满足,默认是 3 行上下文
相关文章推荐
- diff和patch使用指南
- Linux下使用diff和patch制作及打补丁(已经实践可行!)
- linux--difff 和 patch 的使用指南
- diff和patch的使用、patch文件的格式解说
- diff/patch 的使用
- 文件差异和补全功能使用diff_match_patch
- diff和patch使用指南
- diff和patch使用指南
- diff和patch使用指南
- 补丁的制作和使用:diff和patch
- diff和patch使用指南
- 制作和使用补丁文件的方法:diff和patch命令
- diff和patch使用指南
- 使用diff命令制作补丁、patch命令打补丁
- diff/patch 的使用
- diff和patch使用指南
- 使用diff和patch进行简单的文件版本管理
- 使用diff和patch制作及打补丁
- 使用diff同patch工具
- diff和patch使用指南