如何在 Debian/Ubuntu 上安装和运行冲突的软件包?

如何在 Debian/Ubuntu 上安装和运行冲突的软件包?

我想在我的 Debian 机器上安装python3.7和,但它们来自并需要较新版本的,这需要将核心软件包的负载升级到不稳定版本idle-python3.7stablesidlibc如果我按照正常方式做。另外,它还涉及升级或删除大量软件包,无论出于何种原因,这些软件包都指定确切地 python3.5作为他们的依赖之一。我不想那样做。

python3.7由于某种原因我也无法编译;当我尝试时,测试失败了。不过,Debian 维护者设法为我的架构编译了它,所以我想使用他们的版本。

如何安装这些冲突的软件包?

答案1

它们都可以在 Buster 上使用(测试)https://packages.debian.org/search?keywords=python3.7

您应该能够将它们从测试版本向后移植到稳定版本https://backports.debian.org/Instructions/

答案2

警告:这是一个黑客行为。因此,我对其可靠性不做任何承诺。它不太可能破坏您的系统另一种选择, 尽管。


为了做到这一点,我们将在您的文件系统中安装 Debian 的新副本,chroot在其中安装一些软件包,然后在单独的命名空间内创建一种混合系统来运行该程序。某些步骤需要根访问权限,而其他步骤则应该是可选的(但我还没有解决这个问题)。您将需要一个 shell、debootstrapchrootgcc后者是因为我们需要一个自定义工具)。

安装最小的 Debian 实例

为了做到这一点,我们需要一个名为 的程序debootstrap。顾名思义,这个程序可以让您引导 Debian 安装。您可以使用以下命令安装它:

sudo apt-get install debootstrap

现在已经完成了,我们可以开始实际的安装了。

  1. 首先,检查您想要的软件包所在的 Debian 版本。在撰写本文时,
    我的软件包所在的版本是Debian。sid
  2. 现在确定您想要存储此 Debian 映像的位置。
    我很无聊,并且预计需要多次执行此操作,因此我打电话给我的chroot.0并将其直接放入我的 CWD(也是~)。
  3. 运行这个命令:

    sudo debootstrap --variant=minbase sid chroot.0
    

    替换sid为所需的 Debian 版本以及chroot.0您要使用的目录的路径。

    您也可以在此处使用 use--variant=fakeroot并可能避免使用sudo,但这将安装大量额外的软件包(除非您可以组合--variants),并且可能由于权限问题而使答案的其余部分无效。

当它运行时,您可以阅读本答案的下一部分。

安装软件包

这是简单的部分。系统安装完成后,您可以chroot进入其中安装您想要的软件包。

  1. chroot进入最小的 Debian 实例:

    sudo chroot chroot.0
    

    (再次将 chroot.0 替换为您使用的路径)。

  2. 您现在应该处于 root shell 中,可以在其中安装所需的软件包:

    apt install idle-python3.7 python3.7
    
  3. chroot通过运行离开exit

现在我们可以只需运行来自chroot.但是,然后它们将作为root您的主目录运行并与您的主目录隔离,除非您努力在其中创建一个新用户chroot并设置到您的主目录的绑定安装点...此时它开始就像建立一个全新的系统一样。相反,让我们开始创建工具。

创建一个工具

将其保存在某处:

#include <stdio.h>
#include <string.h>
#include <sys/mount.h>
#include <linux/limits.h>

int main(int argc, char **argv) {
    if (argc < 3) {
        printf(
"This is a single-use, disposable program that binds specified directories from\n"
"a chroot's root to the current root.\n"
"\n"
"Argument #1 should be the path to the chroot directory, sans trailing /.\n"
"Subsequent arguments should be paths relative to the root, with preceeding /.\n"
        );
        return 2;
    }
    for (int i = 2; i < argc; i += 1) {
        char source[PATH_MAX];  /* Not really MAX, but quite big. */
        strcpy(&source, argv[1]);
        strcat(&source, argv[i]);
        if (mount(&source, argv[i],
                  NULL, MS_BIND,
                  NULL) == -1) {
            return 1;
        }
    }
    return 0;
}

并用以下命令编译它gcc

gcc bindfromchroot.c -o bindfromchroot

我之所以这么称呼它,bindfromchroot是因为它就是这么做的。我们不能直接使用的原因mount --bind是至少mount需要 2 次调用;其中一个将影响其库mount,另一个将影响其库 - 这两个库都将mount在随后的时间停止运行,并给我们留下一个损坏的名称空间,我们必须exit摆脱它。

现在我们所有的设置都已完成,我们可以运行一些可能应该放入 shell 脚本中的命令。

创建命名空间并运行程序

  1. 运行sudo unshare -m su YOUR_USERNAMEsudo unshare -m su $(id -un)在单独的命名空间中启动 shell作为您(或当前用户)。 “独立的命名空间”很重要;这意味着当我们在主机 Debian 上安装最小 Debian 实例的一部分时,更改将仅适用于我们的新 shell 及其子进程(而不是每个进程)。附加-c /bin/sh到命令可能是个好主意,因为bash在我们运行下一步后,会显示有关发生灾难性错误的烦人的警告消息。
  2. 运行您之前编译的工具。它需要sudo,并且不会真正告诉您通过 保存的错误echo $?,但它可以完成工作。您需要绑定多少 Debian 取决于程序,但我强烈建议尽可能具体,并且不是绑定到/etc/dev/boot。为了让 Python 3.7 在我的机器上运行,我运行了:

    sudo ./bindfromchroot chroot.0 /usr /lib
    
  3. 测试您要运行的程序,例如idle-python3.7。如果不起作用,请检查错误消息,找出缺少的内容,exit然后从步骤 1 重试。

编写 shell 脚本来自动运行您的程序

我为此设计了一条单行线。酌情修改:

sudo unshare -m su wizzwizz4 -c sh -c 'sudo -S ./bindfromchroot chroot.0 /usr /lib; idle-python3.7'

如果您希望保留环境变量,请改用此版本:

sudo -E unshare -m su wizzwizz4 -mc sh -c 'sudo -ES ./bindfromchroot chroot.0 /usr /lib; idle-python3.7'

您可以将 更改sudo -ESsudo -EA来运行环境变量中定义的程序,如果您愿意,SUDO_ASKPASS这可能是图形提示(例如 提供的提示)。git gui

相关内容