史上最硬核的rpm和dpkg依赖问题解决方案_dpkg 依赖

这是因为:

**「依赖检测」「软件安装」不是apt做的,而是dpkg做的。
依赖不满足
「自动修复依赖」**才是apt做的。

所以,如果你下载了一个deb的安装包通过dpkg安装,但依赖不满足的话,他只会提示你依赖缺失,但他不会自动寻找并安装依赖,虽然你仍然可以去下载安装缺失的依赖,但他如果缺失十个八个的,你再手动下载然后dpkg安装也不现实了。

举个例子:我这里下载了一个搜狗输入法的安装包,dpkg -i无法安装但是可以通过apt-get install装上
在这里插入图片描述
要注意:通过apt-get安装本地软件一定要写路径,相对绝对都可以,但不能只写包名。不然它会去源里面找不会装本地的。

上面的方案几乎可以解决80%的安装依赖问题。总结一下:

  • 安装软件就用:「sudo apt-get install xxxx」
  • 遇到依赖问题 :「sudo apt-get -f install」
  • 如果有缺失无法安装,就去网上下,缺什么下什么,下载下来后**「sudo apt-get install ./xxxx」** 把缺的包安装上,再装原来的包。

接下来说说暴力的解决方案:

之所以说暴力,是因为刚才的方式,已经是在我的认知里,工具和系统提供的自动化程序能做到的极限。

如果还是出现了依赖无法满足的问题,比如什么即将安装xxxx但是现在的系统内的版本高于xxxx。

一般这种情况,系统已经不建议你再搞了,你如果非要硬来,很可能会破坏现有的程序依赖结构。

运气好或者你手高,硬装上一点问题没有。
影响小一点,你装了这个软件,另一个软件不能用或者会崩。
影响大一点,有些系统令子不好使了,界面卡死了,资源管理器崩了等等。
影响更大一点,装完用着啥毛病没有,重启后卡在加载过程,再也进不了系统。
「以上这些情况,我全部都遇到过!」

所以下面的搞法,你就当学习知识或看我装逼都行,自己实操,还是要谨慎地折腾。

至少,别在客户机器和生产环境的服务器上硬来。

暴力的解决方案有:

  • 1、–ignore-depends,忽略依赖直接装。
  • 2、解压安装包,删掉依赖字段重新打包
  • 3、修改系统中记录的status文件
  • 4、无视安装失败,直接运行。
  • 5、直接拿到根目录,就地解压。
  • 6、改掉dpkg源码,直接不检测依赖。一个一个说:

1、–ignore-depends

这是所有暴力方案里技术门槛最低的一个,你可以通过dpkg --help 查看–ignore-depends选项:

选项:
......其它选项
  --ignore-depends=<软件包>,...
                             忽略关于 <软件包> 的所有依赖关系。
  --force-...                忽视遇到的问题(参见 --force-help)。
......其它选项

这个选项可以指定要忽略的依赖包。所以安装的时候如果依赖不满足,你直接加上这个参数把依赖忽略的就完了:
在这里插入图片描述
当然,安装不会有任何问题,但是能不能用就看要造化了。

「并不是依赖不满足,装上就一定完全不能用」 有时候只是功能不全而已。

比如你装了一个QQ,它依赖ffmpeg,你忽略了它后直接安装使用很可能没问题,但是一点击视频通话,程序立马就崩掉了。(这是个假设,QQ用啥不用啥我也不知道)

这个方案虽然门槛低,有个致命的缺陷就是太麻烦,我这里缺两个,写两个ignore。安装过程中经常遇到那种一下子缺十个八个的,要写十个八个这样的参数属实费劲。

2、解压安装包,删掉依赖字段重新打包

这个方案可以直接大刀阔斧地把软件包的依赖全干掉,不过稍微需要点技术底子:

「首先你得会解压安装包,其次你得会制作安装包。」

dpkg -X 只会解压出安装包的文件,无法解压出安装包带的脚本和控制信息。

右键提取到此处,解压出来的control和data分开两个压缩包,也不是打包前完美的状态。

这里要用的是

dpkg-deb -R sogoupinyin_xxxx.deb ./sogou

这样解压出来的就是deb在被打包前完完整整的样子,我解压了一个搜狗输入法的安装包为例:
在这里插入图片描述
其他的我们都不用管,直接打开control文件:
在这里插入图片描述
看到红框的部分了吧,直接把这行全部干掉。然后再把拆出来的文件重新打回一个安装包:

fakeroot dpkg-deb --build ./sogou mysogou.deb

这个自己打的mysogou安装包,和搜狗原生安装包唯一的区别就是没有依赖

这下就可以一路畅通无阻,直接装完。

3、修改系统中记录的status文件

和刚才那个方案思路差不多,只不过换了一个突破点,比刚才要更方便一点。

刚才我们突破的思路是:安装包里记录有对软件依赖,全部干掉就没有依赖了。

那么这个方案的思路则是:如果检测依赖发现系统不满足,我们给他伪造一个满足的依赖环境不就完了!

刚才我们说的control文件,所有的deb都有,安装过程中(不是安装后也不是前),他就被记录在了系统里的:「**/var/lib/dpkg/status」**文件里。

这个文件里的内容,也是dpkg -l 命令显示内容的信息来源。

也是我们上面说的,依赖检测时检索系统内是否满足依赖的信息来源。

如果软件通过dpkg -r卸载,这个status文件里的信息不会删除,只会把Status字段改为:deinstall ok
config-files。通过dpkg -P或者dpkg --purge才会把信息完全抹除。

所以,依赖不满足的时候,你可以直接打开这个文件,仿照其他软件的写法,照抄一段加上,把文件名改为缺失的依赖包的名字就可以!dpkg就会认为,系统里有安装这个包,从而解决依赖导致的无法安装的问题。

同样,如果出现依赖的包需要的版本不满足的情况,你也可以直接找到文件里对应的包的信息,改掉Version字段到一个满足需求的版本就可以。

当然,实际上系统里是没有安装这些库的,我们只是骗过了dpkg。

系统里的软件信息一般都写得特别多,这里简单提供个样例,实在不会抄系统的就抄这个:

Package: mtest
Priority: optional
Section: editors
Maintainer: Threedog Team <qiugeyafang@gmail.com>
Architecture: all
Version: 1.0.0
Homepage: http://www.threedog.top
Description: test

只要把Package换成缺失的依赖包的名字,加到status文件里就可以了。记得和其他软件信息之间要有空行。

4、无视安装失败,直接运行。

这个方案之所以可行,是dpkg对软件安装过程的执行机制决定的。dpkg对依赖的处理时机是:「先释放文件,再检测依赖,然后再完成最终配置。」

其实control里还可以写一个字段叫做预依赖:Pre-Depends这个字段的检测级别和时机与“架构Architecture”字段相当。写在这个字段里面的依赖,如果检测不满足,安装会直接中断,不会释放文件,status中不会记录,系统中也不会留下任何痕迹。

所以,当dpkg爆出依赖不满足的问题的时候,其实包里的文件已经释放到系统里了,只不过没有做后续的配置。比如:桌面图标配置、字体配置、文件关联设置、启动触发设置、等等等等。

但这并不妨碍你直接找到他的可执行程序文件直接执行。

如果你不知道他往系统里释放了哪些文件,第一,可以解压看下目录结构,第二,可以通过dpkg --contents xxxx.deb查看包里包含哪些文件。

也可以用dpkg -S +软件名查看已经安装的软件在系统里装了哪些东西。

然后找到二进制可执行文件,一般都会往**/usr/bin/**下面放一个,运气好的话直接执行有可能能跑起来。

5、暴力解压

这个方案属实有点过于暴力并且不合理。直接把安装包移动到根目录下,然后直接dpkg -X解压到当前。然后像刚才一样找二进制可执行程序调用。

前提是你知道这软件包里有什么并且明确它不会影响什么的话。

不然如果解压出的文件破坏了系统的重要文件,那直接就是不可逆的毁降维打击。

而且这么搞完,如何卸载也是一个问题…

6、改dpkg源码

这是技术上最硬核的解决方案。

主要操作方法如下:

从这个地址:https://git.dpkg.org/git/dpkg/dpkg.git

clone下来dpkg源码,在源码里的packages.c里面找到这个dependencies_ok函数。甭管他里面写了多少东西,直接在最开头给他return DEP_CHECK_OK; 或者**return 2;**反正就是个枚举。

然后把项目编译一下生成自己的dpkg用就可以。

我这里自己编译的dpkg多加了一行输出,效果明显一点:
在这里插入图片描述
这个函数改的是对Depends字段的依赖检测

如果是预依赖,Pre-Depends: 字段,要改的是另一个名为depisok的函数。

关于dpkg项目源码的编译,用的是Linux
c项目automake那一套。C/C++老炮闭着眼就编过去了,没入门的萌新连怎么下手都不知道。像我这种刚入门的菜鸡,就得每走一步拿小本本记一下一点,也想这样玩一下的小伙伴可以参考:https://blog.csdn.net/Three_dog/article/details/103418141

有了这个自己编译的dpkg,所有软件都可以无阻碍安装

不过至于装完能不能用,会不会有啥问题,恐怕就得看造化了。

二、解决rpm依赖包

之所以对rpm只字未提有两个原因:

「一是我对它的熟悉程度,远没有dpkg这么深入。」
「二是它真的,相比dpkg,难用的令人抓狂。」

在合法的解决方案上,rpmdpkg没有太大区别。你只需要把上面的对照方案,dpkg+apt-get换成rpm+yum就可以。我们不多赘述了。

主要说说非法方案:

rpm的机制,几乎导致我所有的非法方案完全不可用!

方案一

可用的只有这一个:忽略依赖,这是在rpm上唯一可以对标的非法解决方案,只需要把–ignore-depends 换成**–nodeps**就可以。

其他的,几乎都不行:

方案二

rpm打包的时候,配置信息写在一个**.spec文件里,对标上面的control**文件,这个文件的写法规范恶心程度就不说了,重要的是它无法从打好的rpm安装包里逆向解压出来。

你只能用rpm --scripts -qa xxxx.rpm来查看,而且看到的和它原来真正的写法有很大不同,你甚至可以理解成用objdump看可执行程序的感觉。

这个机制,导致了上面的方案2(解压安装包,删掉依赖字段重新打包)被毙掉。

方案三

rpm 安装到系统中的软件,也有一个文件统一管理,但是!它丫的天杀的居然用的是一个数据库管理的:
在这里插入图片描述
这是编译rpm时候configure参数,这三种数据库编译时可选,安装版一般是Berkeley DB

用数据库管理,就存成二进制数据文件了!就不像我们刚才的status直接修改文本了,而恶心就恶心在(我水平太次也是一方面),这三种数据库我折腾了半天也没找下工具能对他们增删改查!

换句话说这个数据库内容的操作,只有rpm可以,不面向用户。

因此,上面的方案3(修改系统中记录的status软件)也被毙掉了

方案四

rpm的安装只有一种依赖检查的时机,就是在释放文件前。

所以如果出现依赖问题,包里面的文件一滴也不会漏到系统上来,上面的方案4(无视安装失败,直接运行)也被毙掉了。

方案五

方案5,直接暴力解压是可以的。不过上面也说了,这实在是下下下下下下策。

方案六

最后一个,改rpm的源码。

以我的水平,说实话还没有权利对一个成熟的开源项目源码评头论足,但一个不争的事实是:我想像上面那种改dpkg的改法改rpm的源码。折腾了一圈子确实没找到咋改。

所以方案6(修改项目源码)也基本宣告流产。

我想这也是很多人认为dpkg比rpm好用太多的原因之一。

rpm把数据全部用数据库管理起来,看似增强了安全性,但是对于酷爱折腾的Linuxer来说,这种可操控性上带来的降维打击简直无法忍受。

除此之外,它还有非常难用的命令组合;令人沮丧的软件源配置方法;以及地狱难度的打包规规范;打包还不留原文件等等让人觉得它难用的特性在里面!(打包规范真的是折磨人!一不小心打错了,连原文件都没得咯!一个都没得咯!!)

以上,就是以我现有的水平,可以提供的所有针对Linux鬼畜逆天级的软件依赖关系的解决方案。可以看得出来,有些方案是吃一点儿技术底子的。
很多技术问题都是这样,当你对准某一方向钻研到一定深度的时候,很多在常人看来不可能实现的操作,在你手里就可以为所欲为!(我妻善逸:集中一点,登峰造极)
而且我相信,肯定还有我没想到的好办法可以解决这些问题,有可以提供方案或者思路的大佬请一定赐教!

最后,再纠正一个很多人的认知误区:

直到现在,有几乎80%的科普性文章在介绍rpmdeb的时候,把他们与redhatdebian死死的绑定在一起。以至于很多人潜意识里认为:debian系只能用dpkg,红帽系只能用rpm。

其实完全不是。他们的关系,是系统和软件的关系,仅仅是debian自带dpkgapt,红帽自带rpmyum而已。

ubuntu完全可以通过 sudo apt-get install rpm 安装一个rpm,然后通过rpm安装各种rpm格式的安装包。

而centos,也完全可以通过编译安装(因为yum源里没有dpkg 噗~) 一个dpkg,然后安装各种deb格式的安装包。

只要安装的软件所释放出文件没有冲突,两者在系统上的相处模式,甚至可以用举案齐眉、相敬如宾来形容。

根本不像大多数人认为的那样老死不相往来
在这里插入图片描述
在这里插入图片描述

参考链接 :

史上最硬核的 Linux 依赖问题解决方案 : https://mp.weixin.qq.com/s/SAdwtziZnKaNJ2sSEZPnjw

当你在Ubuntu系统上尝试通过`dpkg`命令安装软件包时,可能会遇到依赖关系的问题。`dpkg`是一个Debian包管理工具,它负责处理.deb格式的软件包。如果一个软件包有未安装的依赖项,`dpkg`会在安装前检查并提示你先安装那些依赖。 例如,你可能看到类似这样的错误消息: ``` sudo apt-get install package-name Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable distribution that some required packages have not yet been created or been moved out of Incoming. The following information may help to resolve the situation: The following packages have unmet dependencies: package-name : Depends: dependency1 but it is not going to be installed Recommends: recommendation1 but it will not be installed E: Unable to correct problems, you have held broken packages. ``` 解决这个问题通常需要: 1. **更新包列表**:运行`sudo apt-get update`确保你的源列表是最新的。 2. **安装缺失的依赖**:使用`sudo apt-get install -f`强制安装所有缺失的依赖项,或者根据提示逐个安装它们。 3. **解决推荐(optional)**:虽然不是必需的,但如果推荐的软件包能增强功能,也可以考虑一起安装。 4. **检查软件包版本**:有时候可能是因为你尝试安装的是较旧版本而该版本缺少依赖,可以查看是否有更高版本包含所需的依赖
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值