我想在我的 Debian 机器上安装python3.7
和,但它们来自并需要较新版本的,这需要将核心软件包的负载升级到不稳定版本idle-python3.7
stable
sid
libc
如果我按照正常方式做。另外,它还涉及升级或删除大量软件包,无论出于何种原因,这些软件包都指定确切地 python3.5
作为他们的依赖之一。我不想那样做。
python3.7
由于某种原因我也无法编译;当我尝试时,测试失败了。不过,Debian 维护者设法为我的架构编译了它,所以我想使用他们的版本。
如何安装这些冲突的软件包?
答案1
它们都可以在 Buster 上使用(测试)https://packages.debian.org/search?keywords=python3.7
您应该能够将它们从测试版本向后移植到稳定版本https://backports.debian.org/Instructions/
答案2
警告:这是一个黑客行为。因此,我对其可靠性不做任何承诺。它不太可能破坏您的系统另一种选择, 尽管。
为了做到这一点,我们将在您的文件系统中安装 Debian 的新副本,chroot
在其中安装一些软件包,然后在单独的命名空间内创建一种混合系统来运行该程序。某些步骤需要根访问权限,而其他步骤则应该是可选的(但我还没有解决这个问题)。您将需要一个 shell、debootstrap
和chroot
(gcc
后者是因为我们需要一个自定义工具)。
安装最小的 Debian 实例
为了做到这一点,我们需要一个名为 的程序debootstrap
。顾名思义,这个程序可以让您引导 Debian 安装。您可以使用以下命令安装它:
sudo apt-get install debootstrap
现在已经完成了,我们可以开始实际的安装了。
- 首先,检查您想要的软件包所在的 Debian 版本。在撰写本文时,
我的软件包所在的版本是Debian。sid
- 现在确定您想要存储此 Debian 映像的位置。
我很无聊,并且预计需要多次执行此操作,因此我打电话给我的chroot.0
并将其直接放入我的 CWD(也是~
)。 运行这个命令:
sudo debootstrap --variant=minbase sid chroot.0
替换
sid
为所需的 Debian 版本以及chroot.0
您要使用的目录的路径。您也可以在此处使用 use
--variant=fakeroot
并可能避免使用sudo
,但这将安装大量额外的软件包(除非您可以组合--variant
s),并且可能由于权限问题而使答案的其余部分无效。
当它运行时,您可以阅读本答案的下一部分。
安装软件包
这是简单的部分。系统安装完成后,您可以chroot
进入其中安装您想要的软件包。
chroot
进入最小的 Debian 实例:sudo chroot chroot.0
(再次将 chroot.0 替换为您使用的路径)。
您现在应该处于 root shell 中,可以在其中安装所需的软件包:
apt install idle-python3.7 python3.7
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 脚本中的命令。
创建命名空间并运行程序
- 运行
sudo unshare -m su YOUR_USERNAME
或sudo unshare -m su $(id -un)
到在单独的命名空间中启动 shell作为您(或当前用户)。 “独立的命名空间”很重要;这意味着当我们在主机 Debian 上安装最小 Debian 实例的一部分时,更改将仅适用于我们的新 shell 及其子进程(而不是每个进程)。附加-c /bin/sh
到命令可能是个好主意,因为bash
在我们运行下一步后,会显示有关发生灾难性错误的烦人的警告消息。 运行您之前编译的工具。它需要
sudo
,并且不会真正告诉您通过 保存的错误echo $?
,但它可以完成工作。您需要绑定多少 Debian 取决于程序,但我强烈建议尽可能具体,并且不是绑定到/etc
、/dev
或/boot
。为了让 Python 3.7 在我的机器上运行,我运行了:sudo ./bindfromchroot chroot.0 /usr /lib
- 测试您要运行的程序,例如
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 -ES
为sudo -EA
来运行环境变量中定义的程序,如果您愿意,SUDO_ASKPASS
这可能是图形提示(例如 提供的提示)。git gui