编者按:本文介绍了一些暴力破解RPM和DEB包依赖的另类方法。一种生存方式。至于这样做是否合适,那是见仁见智的事情,但这种不放弃的强硬态度,值得赞赏。另外,本文中的一些观点仅代表作者的理解,不一定正确,大家可以争论。本文转载经作者授权。最近刚好在研究dpkg和rpm,对linux的依赖有了更深的了解。网上看了很多,所有关于Docker、虚拟机、编译安装、各种备选方案的回答,都是为了日常繁重的业务,没时间折腾不得不做出的妥协和让步。而我们以技术为导向,“我向来喜欢硬汉!”加固Linux软件安装依赖的方法有很多种,我将分为两类!“一种合法性,另一种暴力。”首先,合法的解决方案也是大家都知道的解决方案:sudoapt-getinstallxxxxx一般情况下会和软件依赖一起安装。如果这个过程依赖安装失败,执行:sudoapt-get-finstall一次,不要两次,只要源码里有,只要保证依赖顺畅,不管执行多少依赖几次,就可以安装了。如果有依赖源,则找不到。这个坑不能踩。解决方法是:找到缺失库的安装包,手动下载。然后通过sudodpkg-ixxxx.deb安装。找到需要手动下载的安装包主要有两种方式:百度搜索,直接搜索包名+版本号通过源带上关键词deb。百度直接搜库我就不多说了,也说说怎么通过源码找吧。你在网上搜索国内的ubuntu源。你会发现很多这样写的:debhttps://mirrors.tuna.tsinghua.edu.cn/ubuntu/xenialmainrestricteduniversemultiverse这其实就是apt-get工具配置的源地址,也是一个实际的URL。直接用浏览器访问即可,比如上面的:https://mirrors.tuna.tsinghua.edu.cn/ubuntu/xenialmainrestricteduniversemultiverse其实代表的是:https://mirrors.tuna.tsinghua。edu.cn/ubuntu/pool/xenial/该路径下的main、restricted、universe、multiverse目录:apt-get工具会自动在这四个目录下搜索对应的软件包进行下载安装。在一些特殊情况下,比如本机网络受限,但是浏览器开启了代理访问外网。apt-get无法从源码获取软件,可以从这里手动找到对应的软件包,下载,然后使用dpkg安装。比如这里,手动找到mysql安装包的路径,然后点击直接下载:刚才说了apt-getinstall不能修复依赖。手动下载并打包这些缺失的安装包后,就可以使用apt-get安装了,不在打包上。这是一个非常合理合法的解决方案。再加一个法术,可以试试:apt-getinstalllocalsoftwarepackage这是因为:“依赖检测”和“软件安装”不是apt-get做的,而是dpkg做的。依赖性不满足“自动修复依赖性”是apt-get所做的。所以,如果你下载了一个deb安装包,通过dpkg安装,但是依赖不满足,它只会提示你缺少依赖,而不会自动查找并安装依赖。虽然你仍然可以下载并安装缺少的依赖项,但是如果他缺少十个或八个,你手动下载然后dpkginstall是不现实的。例如:我这里下载了一个搜狗输入法安装包,dpkg-i无法安装,但是可以通过apt-getinstall安装:注意:通过apt-get安装本地软件时,一定要写路径,这是相对绝对的,但不仅仅是包名。不然就会去源码里找本地安装不了的东西。以上解决方案几乎可以解决80%的安装依赖问题。总结一下:安装软件使用:sudoapt-getinstallxxxx如果遇到依赖问题:sudoapt-get-finstall如果缺少什么安装不了,就去网上下载缺少的.下载后,sudoapt-getinstall./xxxx安装缺少的包,再安装原包。接下来说说暴力解决。之所以说暴力,是因为刚才的方法在我的认知中已经是工具和系统提供的自动化程序所能做到的极限了。如果还是出现依赖无法满足的问题,比如什么要安装xxxx但是系统中当前版本高于xxxx。一般这种情况下,系统是不建议你再做的。如果硬要去做,很可能会破坏现有的程序依赖结构。如果运气好或者手头高,硬装是没有问题的。影响较小,如果安装此软件,其他软件将无法运行或崩溃。影响大一点,一些系统命令不能正常运行,界面卡死,资源管理器崩溃等等。影响大了点,安装后没问题,重启后卡在加载过程中,无法再进入系统。“以上情况我都遇到过!”所以,在下面的方法中,你可以把它当作学习知识或者看我装,自己去实践,或者小心折腾。至少,不要在客户端机器和生产服务器上强制使用它。暴力解决方案是:--ignore-depends,忽略依赖,直接安装。解压安装包,删除依赖项,重新打包。修改系统记录的状态文件。安装失败无视,直接运行。直接获取根目录,就地解压。更改dpkg的源码,直接不检测依赖。一一介绍:1.--ignore-depends这是所有暴力方案中技术门槛最低的一个。可以通过dpkg--help查看--ignore-depends选项:options:......其他选项--ignore-depends=,...忽略对的所有依赖。--force-...忽略遇到的问题(参见--force-help)。......Otheroptions这个选项可以指定要忽略的依赖包。所以如果安装的时候不满足依赖,可以直接加上这个参数忽略依赖:当然安装不会有问题,但是能不能用就看运气了。“不是依赖不满足,安装完肯定是完全不能用了。”有时只是功能不完善而已。比如你安装一个QQ,它依赖ffmpeg,你可以不理它,直接安装使用,但是点视频通话,程序立马崩溃。(这个是假设,不知道QQ用的什么不用的)这个方案虽然门槛低,但是有个致命的缺陷就是太麻烦了。我这里少了两个,写了两个忽略参数。安装过程中经常遇到一下子少了十个八个参数,写个十个八个参数真的很费力。2、解压安装包,删除依赖字段,重新打包这个方案可以直接杀掉软件包的所有依赖,但是需要一点技术基础:“首先你得会解压安装包,其次你必须能够制作安装包。”dpkg-X只会解压安装包的文件,不能解压安装包附带的脚本和控制信息。“右键”->“解压到这里”,解压后的控件和数据分离成两个压缩包,不是打包前的完美状态。这里使用的是dpkg-deb-Rsogoupinyin_xxxx.deb./sogou。解压出来的就是打包前的完整deb。我以解压一个搜狗输入法安装包为例:我们不需要其他的直接打开控制文件即可:看到红框部分,将这一行全部删除即可。然后将删除的文件重新打回一个安装包:fakerootdpkg-deb--build./sogoumysogou.deb,这个是我自己创建的mysogou安装包,和搜狗原安装包唯一的区别就是没有依赖。现在可以一路畅通无阻,直接安装完成。3、修改系统记录的状态文件的思路和之前的方案差不多,只是改了一个突破点,比之前方便多了。刚才我们突破的思路是:安装包里面记录了软件依赖,全部杀掉就没有依赖了。那么这个方案的思路就是:如果检测依赖发现系统不满意,我们就给他锻造一个满意的依赖环境,就完事了!刚才我们说的控制文件里面有所有的deb文件。在安装过程中(不是安装后或安装前)记录在系统:/var/lib/dpkg/status文件中。该文件中的内容也是dpkg-l命令显示的内容的信息来源。也就是我们上面说的,依赖检测时检索系统中依赖是否满足的信息来源。如果通过dpkg-r卸载软件,status文件中的信息不会被删除,只是Status字段会变成:deinstallokconfig-files。只有通过dpkg-P或dpkg--purge才会将信息彻底清除。所以,当依赖不满足的时候,可以直接打开这个文件,按照其他软件的写法,复制一段添加进去,把文件名改成缺少的依赖包的名字!dpkg会认为系统中安装了这个包,从而解决无法安装依赖的问题。同样,如果依赖包不满足要求的版本,也可以直接在文件中查找对应包的信息,将Version字段修改为满足要求的版本。当然,这些库实际上并没有安装在系统上,我们只是欺骗了dpkg。系统中的软件信息一般都写了很多。这是一个简单的例子。如果实在不会copy系统,就copy这个:Package:mtestPriority:optionalSection:editorsMaintainer:ThreedogTeamArchitecture:allVersion:1.0.0Homepage:http://www.threedog.topDescription:test将Package替换为缺失依赖包的名称,添加到status文件即可。记得和其他软件信息之间有一个空行。4.忽略安装失败,直接运行。这个方案之所以可行,是由dpkg对软件安装过程的执行机制决定的。dpkg处理依赖的时机是:“先释放文件,再检测依赖,最后完成配置”。其实在控制文件中也可以写一个叫做pre-dependence的字段:Pre-Depends。该领域的检测水平和时间与建筑领域相当。如果这个字段写的依赖不满足,会直接中断安装,不会释放文件,不会记录状态,不会在系统中留下任何痕迹。所以,当dpkg破解依赖不满足的问题时,其实包中的文件已经发布到系统中了,只是没有做后续的配置。比如:桌面图标配置、字体配置、文件关联设置、启动触发设置等。但这并不妨碍你直接找到他的可执行程序文件,直接执行。如果你不知道他释放了哪些文件到系统中:首先你可以解压看看目录结构;其次,您可以使用dpkg--contentsxxxx.deb检查包中包含哪些文件。也可以使用dpkg-S软件名查看系统安装了哪些安装的软件。然后找到二进制可执行文件,一般在/usr/bin/下放一个,运气好的话直接执行就可以运行了。5.暴力解压有点太暴力了,不讲道理。将安装包直接移动到根目录,然后直接用dpkg-X解压到当前。然后像以前一样找到二进制可执行程序调用。只要您知道包装中有什么并且知道它不会影响什么。否则,如果解压后的文件破坏了系统的重要文件,那将是对降维不可逆转的打击。而这样做之后,如何卸载也是个问题……6.修改dpkg源码。这是最难的技术方案。主要操作方法如下:从这个地址克隆dpkg源码:https://git.dpkg.org/git/dpkg/dpkg.git,找到源码中packages.c中的dependencies_ok函数。不管里面写了多少东西,给它returnDEP_CHECK_OK就可以了;或返回2;一开始,无论如何它都是一个枚举。然后编译工程生成自己的dpkg并使用。我这里编译的dpkg多了一行输出,效果比较明显:这个函数改变了Depends字段的依赖检测。如果是预依赖Pre-Depends字段,需要改另一个函数depisok。关于dpkg工程源码的编译,使用了LinuxC工程automake。C/C++老手都是闭着眼睛编译的,没下手的萌新根本不知道怎么下手。对于我这种刚入门的菜鸟来说,每走一步都要带着一个小笔记本,想这样玩的朋友可以参考:https://blog.csdn.net/Three_dog/article/details/103418141有了这个自己编译的dpkg,所有软件都可以无障碍安装。不过至于安装后能不能用,会不会出什么问题,恐怕要看运气了。说完dpkg的所有解决方案,rpm没有提到rpm的原因有两个:“一个是我对它的熟悉程度不如dpkg”。“其次,确实如此,与dpkg相比,难用得要命。”在合法解决方案方面,rpm和dpkg之间没有太大区别。你只需要将上面的控制方案,dpkg+apt-get替换成rpm+yum即可。我们不会详细介绍。主要说一下非法解:rpm的机制几乎让我所有的非法解完全不可用!选项1只有一个:ignoredependencies,这是唯一可以在rpm上匹配的非法解决方案,只需将--ignore-depends替换为--nodeps即可。其他的几乎不可能:第二个选项用rpm打包的时候,配置信息写在a。将做好的rpm安装包反向解压。只能用rpm--scripts-qaxxxx.rpm来查看,看到的和它原来的真实写法有很大的不同。你甚至可以理解为用objdump看可执行程序的感觉。这种机制导致了上面第二种方案的死亡(解压安装包,删除依赖字段,重新打包)。解决方案3rpm安装在系统中的软件也有统一的文件管理,但是!真他妈的用了数据库管理:这是编译rpm时的configure参数。这三个数据库在编译时是可选的,安装版本一般是BerkeleyDB。通过数据库管理,以二进制数据文件的形式存储!又不是我们直接在状态里修改文字,恶心恶心(我水平太低,也是一方面)。这三个数据库我折腾了好久都没找到增删改查的工具!换句话说,这个数据库内容的操作只能通过rpm来完成,不能给用户。因此,上述方案三(修改系统记录的状态软件)也被否决。方案四rpm的安装只有一次依赖检查时机,即释放文件前。因此,如果存在依赖问题,则包中的任何文件都不会泄露给系统。上面的方案4(忽略安装失败,直接运行)也被kill掉了。方案五直接暴力减压是可以的。但是,如上所述,这确实是一个糟糕的策略。解决方案6最后一个是更改rpm的源代码。以我的水平,说实话,我无权评论一个成熟的开源项目的源码,但一个不争的事实是:我想像上面改dpkg的方法,就是改rpm的源码。折腾了一圈,实在是找不到什么变化。因此,方案六(修改项目源码)基本宣告作废。我想这也是很多人认为dpkg比rpm好用得多的原因之一。rpm把所有的数据都用一个数据库来管理,看似增强了安全性,但是对于爱折腾的Linuxer来说,这种可控性带来的降维打击简直难以承受。此外,它还有一个非常困难的命令组合;令人沮丧的软件源配置方法;以及极难的包装规范;包装不留原文件等,让人觉得很难用。!(打包说明真折磨人!万一不小心打错了,连原文件都得不到!你什么都得不到!!)根据我目前的水平提供。天空级软件依赖解析。可见有些方案是有点技术基础的。许多技术问题就是这种情况。当你在某个方向钻研到某个深度,很多常人做不到的操作都可以在你手中完成!(我老婆善意:专心致志,登峰造极)而且我相信一定有很好的办法来解决这些我没有想到的问题。如果有哪位大佬能提供解决方案或者思路,请赐教!最后,纠正一个很多人都有的误解。直到现在,几乎80%的科普文章在介绍rpm和deb文件时,都将其与RedHat和Debian捆绑在一起。所以很多人下意识的认为:Debian系统只能用dpkg,RedHat系统只能用rpm。一点也不。它们之间的关系就是系统和软件的关系,就是Debian自带dpkg和apt,RedHat自带rpm和yum。Ubuntu可以通过sudoapt-getinstallrpm安装一个rpm系统,然后通过rpm安装各种rpm格式的安装包。而CentOS也可以通过编译安装(因为yum源中没有dpkg,噗~)一个dpkg,然后安装各种deb格式的安装包。只要安装的软件释放的文件没有冲突,两人在系统上的相处方式甚至可以用恭宾来形容。它根本不像大多数人想象的那样陈旧和死气沉沉: