💻
Notes-CS
  • INTRO
  • 操作系统
    • 操作系统原理
      • 操作系统概述
        • 操作系统的分类
          • 批处理操作系统
          • 分时操作系统
          • 实时操作系统
          • 个人计算机操作系统
          • 网络操作系统
          • 分布式操作系统
          • 嵌入式操作系统
        • 操作系统的运行环境与机制
          • 中断与异常
          • 系统调用
      • 进程与线程
        • 进程
        • 线程
        • 协程
      • 处理器调度
      • 同步机制
      • 存储模型
      • 文件系统
        • 分区类型
      • 输入输出系统
    • 通用操作系统
      • GNU/Linux
        • Linux 内核
          • Linux 启动过程
          • 几种内核映像的区别
          • 终端设备
          • Ptrace
        • 可执行文件 ELF
        • 文件系统
          • swap
          • Linux 文件系统目录描述
          • 特殊文件
        • 软件生态
          • 基于 Linux 的 OS
            • Arch Linux
            • CentOS
            • Debian
            • Fedora
            • Gentoo
            • Kali
            • OpenSUSE
            • OpenWRT
            • Ubuntu
          • 桌面环境
            • KDE
            • GNOME
            • Xfce
            • DDE
            • Unity
            • MATE
          • 包管理器
            • apt
              • apt install
            • yum
            • pacman
        • Utils
          • dd
          • motd
          • 系统状态分析工具
          • TTY和PTS
          • SysVInit 与 SystemD
          • Linux 系统参考手册
          • 文本IO处理
            • awk
            • sed
            • cut
            • grep
            • xargs
            • diff & patch
      • MacOS
        • Darwin 内核
        • 快捷键
      • Windows
        • NT 内核
        • 可执行文件 PE
        • 文件系统组织
        • 发行版本
          • 古董
            • Windows 3.1
            • Windows 95
            • Windows 98
            • Windows 2000
            • Windows me
            • Windows Vista
            • Windows 8
          • Windows XP
          • Windows 7
          • Windows 10
            • 常用快捷键
      • Android
        • 系统结构
        • 软件包格式 APK
        • 版本历史
    • 通用系统概念
      • ANSI转义序列
        • 终端颜色控制符
      • POSIX
      • 虚拟化
        • 常见虚拟化OS镜像格式
      • Secure Boot
      • 常见文件系统
        • NTFS
        • FAT
        • JFFS
        • tmpfs
  • 编程
    • 编程语言
      • C
        • 语法
          • const
          • typedef
        • 库
          • C standard library(libc)
            • glibc
              • ptrace
          • C POSIX library
            • pthread
        • GNU C
        • 其它
          • 链接库的构成
          • 头文件规范
          • 动态链接库
      • C++
        • 语法
        • 库
          • SL/STL
            • 容器
              • vector
              • string
              • unordered_map
            • 迭代器
            • 其它
              • man page 解决方案
        • 面向对象
          • 重写与重载
            • 运算符重载
      • Python
        • 语法
        • 包
          • 内建
          • 第三方
            • requests
        • 其它
          • PyPI 的使用
          • 内建模块
      • Rust
        • 入门实例
      • Java
      • shell
        • set
    • 数据结构与算法
      • 数据结构
        • 栈
        • 队列
        • 链表
        • 哈希表
        • 并查集
        • 堆
        • 树
          • 二叉树
        • 图
      • 算法
        • 算法基础
          • 枚举
          • 模拟
          • 递归 & 分治
          • 贪心
          • 排序
        • 搜索
        • 动态规划
        • 字符串
        • 数学
          • 快速幂
        • 图论
    • 编译原理
      • 编译器与解释器
      • 词法分析
      • 语法分析
      • 类型检查
      • 中间代码生成
      • 目标代码生成
      • 代码优化
    • 软件工程
      • 编程范式
        • 指令式
          • 过程式
          • 块结构
          • 结构化
          • 非结构化
          • 递归
          • 模块化
        • 面向对象
          • 基于类
          • 基于原型
        • 声明式
          • 函数式
            • 纯函数式
            • 函数响应
        • 多态
          • 多分派
          • 泛型
            • 模板
        • 元编程
          • 宏
          • 元类
          • 反射式
      • 开发方法
        • 敏捷开发
        • 过程模型
          • 瀑布模型
          • V 模型
          • 增量模型
          • 螺旋模型
      • 开发流程
        • 问题定义
        • 可行性研究
        • 需求分析
        • 概要设计
        • 详细设计
        • 编码与测试
        • 运行与维护
      • 开源软件
        • 版本后缀规则
        • 开源协议
          • GPL
          • LGPL
          • MIT
          • BSD
          • Apache
          • Mozilla
  • 信息安全
    • 信息安全原理
      • IoT
        • 交叉编译
        • 固件格式
        • 常见协议
          • UPnP
      • 二进制
        • 常见漏洞
          • Stack Overflow
          • Format String Bug
          • Integer Overflow
          • Double Free
          • Use After Free
          • Race Condition
        • 通用工具
          • IDA
          • ghidra
          • pwntools
          • binutils
          • GDB
          • 脚本工具
            • LibcSearcher
            • main_arena_offset
            • one_gadget
            • ROPgadget
        • 常用技术
          • 符号执行
            • 传统符号执行
            • 现代符号执行
          • 模糊测试
      • Web
        • 常见漏洞
          • SQLi - SQL injection
          • XSS - Cross Site Scripting
            • 基本原理
          • CSRF - Cross Site Request Forgery
          • SSRF - Server-Side Request Forgery
          • XXE - XML External Entity
            • 基本原理
        • 通用工具
          • Burp Suite
          • Wireshark
      • 密码学
        • 流密码
          • XOR
          • RC4
        • 分组密码
          • DES - Data Encryption Standard
          • AES - Advanced Encryption Standard
        • 公钥密码
          • RSA
            • 欧几里得算法
            • 扩展欧几里得算法
            • 中国剩余定理
            • 共模攻击
          • 椭圆曲线算法
        • 数字签名
        • 数据校验
          • CRC
      • 区块链
        • 以太坊
    • 信息安全实践
      • 环境准备
        • IOT
          • 固件获取
          • 固件打包与解包
          • QEMU 模拟
          • 交叉编译
          • 制作文件系统镜像
          • UART 调试
      • 漏洞挖掘
        • 漏洞概览
          • 漏洞编号与管理机构
        • 漏洞挖掘技术
          • 静态分析
          • 模糊测试
            • 工具与框架
              • AFL
          • 污点分析
          • 符号执行
            • 工具与框架
              • Angr
              • KLEE
              • S2E
      • 安全开发
      • 渗透测试
        • shell
        • 网络空间测绘系统
          • quake
          • shodan
        • 内网渗透
          • Linux 靶机
            • 信息搜集
            • 持久化
            • 痕迹清理
        • 工具与框架
          • Metasploit
    • 论文与演示
  • Web 与计算机网络
    • 协议栈
      • 链接层
        • PPP
        • ARP
        • MAC
      • 网络层
        • IP - Internet Protocol
          • IPv4
            • IPv4 分级式寻址
            • IPv4 私有地址划分
          • IPv6
        • ICMP - Internet Control Message Protocol
      • 传输层
        • TCP
        • UDP
        • TLS/SSL
      • 应用层
        • UPnP
        • HTTP
        • DNS
        • FTP
    • Web
      • 浏览器
        • Chrome
          • 内建功能
          • 快捷键
        • Tor
      • Web容器
        • Apache
        • Nginx
        • lighttpd
      • CGI
      • MIME type
      • 搜索引擎
  • 体系结构与硬件
    • 计算机体系结构
      • 指令集
        • X86
        • AMD64
        • ARM
        • RISC-V
        • MIPS
    • 设备与接口
      • 接口协议
        • UART
        • USB
        • HDMI
        • PCI
      • 存储设备
        • 固态硬盘
          • 闪存颗粒 ?LC
        • 识别 Linux上的设备(磁盘)类型
        • 字符设备与块设备
        • MTD
      • 网络设备
        • 路由器
        • 交换机
        • 网卡与虚拟网卡
        • 光接入网络
          • 光猫
  • 数学
    • 离散数学
    • 线性代数
    • 概率与统计
    • 计算理论
  • 软件与框架
    • 通用
      • bash
      • Vim
        • 配置
        • 快捷键
        • 插件
        • VIM Script
      • git
      • Tmux
      • gdb
      • ssh
      • make
      • 双拼
    • 专用
      • 🪜Untitled
        • clash
      • gcc
      • nmap
      • QEMU
        • QEMU source
        • 模拟 raw Linux
        • 模拟发行版
      • docker
      • buildroot
      • burpsuite
    • 轮子
      • LaTeX
      • LLVM
      • libpcap
  • reCTF
    • PWN
      • QEMU PWN
      • Kernel PWN
    • Web
    • Reverse
    • Crypto
    • MISC
  • 资源
    • 学习站
      • 安全学习站
        • 门户
        • 论坛
        • 教程
        • 会议
        • 博客
      • 编程学习站
        • 文档
    • 工具站
      • 安全工具站
        • 二进制
        • Web
        • IoT
        • 社工
      • 应用工具站
  • 实践记录
    • 事件
      • 对于 UDPt 漏洞的跟踪实践
    • 编译
      • alware 静态交叉编译
      • buildroot 编译 arm target
由 GitBook 提供支持
在本页
  • 摘要
  • diff 介绍
  • diff 语法与文件格式
  • patch 介绍
  • 应用
  • 制作补丁
  • 应用补丁
  • 修正补丁
  • 再次应用补丁
  • 总结
  1. 操作系统
  2. 通用操作系统
  3. GNU/Linux
  4. Utils
  5. 文本IO处理

diff & patch

摘要

在 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 
linux
linux
linux
linux

$ cat test2
locez
linux
locez
linux

此时输入 diff -urN test1 test2 会输出以下信息:

--- 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

先看前面 2 行,这两行为文件的基本信息,--- 开头为改变前的文件,+++ 开头为更新后的文件。

--- 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.5 3.5 版本的默认配置文件,未修改

  • rc.lua.myconfig 基于 3.5 版本的个人配置文件

  • rc.lua.4.2 4.2 新默认配置,未修改

思路为利用 diff 提取出个人配置与 3.5 默认配置文件的增量补丁,然后把补丁应用在 4.2 的文件上实现迁移。

制作补丁

$ diff -urN rc.lua.3.5 rc.lua.myconfig  > mypatch.patch

应用补丁

$ patch rc.lua.4.2 -i mypatch.patch -o rc.lua
patching 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

显然应用没有完全成功,其中在 38 行以及 55 行应用失败,并记录在 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.lua
patching 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 个非常重要的要素:

  1. 要修改的内容是否匹配?特别是要删除的

  2. 上下文是否满足,特别是距离要修改的地方前后一行,以及上下文的行数是否满足,默认是 3 行上下文

上一页xargs下一页MacOS

最后更新于3年前