1 Star 0 Fork 11

coder_lw / wiki

forked from deepinwiki / wiki 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
制作补丁和安装、卸载补丁.md 3.83 KB
一键复制 编辑 原始数据 按行查看 历史
htqx 提交于 2023-04-16 21:55 . 整理分开文件夹和文件

制作补丁和安装、卸载补丁

前言

有时候我们想更新某个文件夹,但是又知道新旧版本之间,实际变化并不大,这时候就可以考虑补丁技术。

制作补丁

制作补丁用的是diff命令:

制作目录补丁

# -r 递归文件夹
# -u 用统一格式
# --unidirectional-new-file 当新版有,旧版没,创建。当旧版有,新版无,忽略(用于制作部分更新的补丁)
# -N 新版有,创建,新版无,设置为空文件(用于制作完全一致的镜像补丁)
# a 旧文件夹,假设存在 x,y
# b 新文件夹, 假设存在 y,z
# 输出补丁文件 b.patch
diff -ru --unidirectional-new-file a b >b.patch
# 注意理解补丁文件的基本原理
# 旧a/y 新b/y 
# +增加的内容
# -删除的内容
# 因此,更新补丁实质保留了一份原始的数据,并添加了一份新的数据,而相同的即忽略(但不管是更新后还是更新前的文件都存在这些数据)。因此可以通过补丁文件来反向操作,取消补丁

制作文件补丁

# new 是修改后的文件
# old 是原版
# -p 是输出修改的函数(源文件)
# -u 是统一格式
diff -up old new > old.patch

安装、卸载补丁

补丁的应用和卸载使用patch 命令:

对目录打补丁

# 一、安装补丁
# 如,当前路径/home
# -p0 表示对补丁文件里面的 a/* 操作,即操作/home/a/*
# -p1 表示对 * 操作,也就是去除一层路径前缀,即操作/home/*
# -i 补丁文件
patch -p0 -i b.patch

# 更好的做法,为啥?等下就知道
cd ./a
patch -p1 -i ../b.patch

# 二、卸载补丁
# -R 增加变删除,删除变增加
patch -R -p1 -i ../b.patch

为何要进入第一层目录打补丁:

#如果是p0,空文件将会变成对b/*操作,而不是对a/*操作,这点patch程序相当死板(不知道是不是bug)

# 因此,制作补丁文件应遵从如下规则:
# 1. a b 路径对称,且简单,不要 i/o/a , p/b 这种,因为路径会被记录进补丁文件
# 2. 进入 a 来并去除前缀操作打补丁。
# 3. 单个文件的补丁,不用这么严格

# 如例子:
ln -sr /lib/x86_64-linux-gnu original
ln -sr glibc/lib updated
diff -u --unidirectional-new-file original updated >glibc.patch 
cd original
patch -p1 -i /home/glibc.patch #为系统的glibc打补丁
patch -R -p1 -i /home/glibc.patch #取消补丁

对文件打补丁

# 对当前目录下的文件应用补丁
# -i : --input
patch -i old.patch

# 卸载补丁(恢复原样)
# -R : --reverse
patch -Ri old.patch

二进制文件和全镜像补丁


# -a 二进制文件默认忽略,a参数添加它,但是出来的文件会非常大
diff -au /bin/ls a/x > ls.patch

# 全镜像补丁,添加N
diff -aNru a b > full.patch

案例-升级glibc库

glibc 是很底层的库,如果升级失败,后果严重,因此使用补丁,失败也能够取消补丁来回退。

# 创建路径快捷方式
mkdir glibc
cd glibc
ln -rs /opt/glibc/bin bin
ln -rs /usr/bin obin
ln -rs /opt/glibc/lib lib
ln -rs /usr/lib/x86_64-linux-gnu olib
ln -rs /opt/glibc glibc-exclude
ln -rs /usr/ oglibc

# 建立补丁
diff -au --unidirectional-new-file obin bin >bin.patch

diff -au --unidirectional-new-file olib lib > lib.patch

# -x 排除文件或文件夹
diff -aur --unidirectional-new-file -x "bin" -x "lib" oglibc glibc-exclude > glibc-exclude.patch

# 打补丁
su #进入管理员模式
glibc=$(pwd) #保存当前路径

pushd obin; patch -p1 -i $glibc/bin.patch; popd;

pushd olib; patch -p1 -i $glibc/lib.patch; popd;

pushd oglibc; patch -p1 -i $glibc/glibc-exclude; popd;


# 如果失败
pushd obin; patch -R -p1 -i $glibc/bin.patch; popd;

pushd olib; patch -R -p1 -i $glibc/lib.patch; popd;

pushd oglibc; patch -R -p1 -i $glibc/glibc-exclude; popd;

参考

1
https://gitee.com/coder_lw/wiki.git
git@gitee.com:coder_lw/wiki.git
coder_lw
wiki
wiki
master

搜索帮助