我必须使用官方支持 RHEL、SuSE (SLE[DS]) 和某个 Ubuntu LTS 版本的第三方软件。
不幸的是,我在所有系统上都使用 Debian。
如果我运行该软件的安装程序脚本,它会退出并显示错误消息(“不支持分发”)并且不会安装。
安装下载附带一个.deb
实际上适用于 Ubuntu 的包。当且仅当包含 Ubuntu 版本(简单的字符串检查).deb
时,安装程序脚本才会安装此文件。/etc/os-release
但好消息是:您只需找到该文件的名称.deb
并在 Debian 上手动安装它dpkg -i
,安装的软件就可以完美运行。 :)
只有一件事我不满意:该软件的自动更新功能使用上面提到的安装程序脚本,它不喜欢 Debian。因此,我不会对此应用程序进行无人值守的升级:更新过程成功下载了包括该.deb
文件的新版本,但启动了不情愿的安装程序脚本,而不仅仅是安装该.deb
文件。安装程序退出并出现错误。更新失败。 :((我不知道为什么供应商不简单地提供一个 URL /etc/apt/sources.list.d
,而是制作了这个令人毛骨悚然的自定义更新机制。)
我必须手动下载新版本,提取 *.deb 文件并重新安装。
您对此有什么想法或建议吗?
我可以简单地编辑文本文件/etc/os-release
以显示“Ubuntu”而不是“Debian”。那么问题就迎刃而解了。但这会对系统产生副作用吗,例如出现问题apt-get update && apt-get upgrade
?
或者我可以/etc/os-release
为某个 systemd 服务单元“挂载”一个假文件吗?那么只有这个服务认为它在 Ubuntu 而不是 Debian 上运行?也许像 chroot 之类的东西?但我是否必须手动使 chroot 目录中的整个系统副本保持最新状态?
答案1
或者我可以为某个 systemd 服务单元“挂载”一个假的 /etc/os-release 文件吗?
这正是 systemdBindPaths
和BindReadOnlyPaths
选项的用途(文档):
BindPaths=
,BindReadOnlyPaths=
配置特定于单元的绑定安装。绑定安装使特定文件或目录在文件系统的单元视图中的其他位置可用。使用此选项创建的任何绑定挂载都特定于该单元,并且在主机的挂载表中不可见。此选项需要一个以空格分隔的绑定安装定义列表。每个定义由冒号分隔的源路径、目标路径和选项字符串三元组组成,其中后两个是可选的。如果仅指定源路径,则源和目标将被视为相同。选项字符串可以是“rbind”或“norbind”,用于配置递归或非递归绑定安装。如果省略目标路径,则选项字符串也必须省略。每个绑定挂载定义都可以带有“-”前缀,在这种情况下,当其源路径不存在时,它将被忽略。
BindPaths=
创建常规可写绑定挂载(除非源文件系统挂载已标记为只读),同时BindReadOnlyPaths=
创建只读绑定挂载。这些设置可以多次使用,每次使用都会附加到设备的绑定安装列表中。如果将空字符串分配给这两个选项中的任何一个,则在此之前定义的整个绑定安装列表将被重置。请注意,在这种情况下,只读和常规绑定安装都会重置,无论使用这两个设置中的哪一个。
考虑一个运行指向该目录的 Web 服务器的简单服务/etc
:
[Service]
Type=exec
ExecStart=/usr/sbin/darkhttpd /etc --port 8080
如果我运行此服务并访问 http://localhost:8080/os-release,我将看到来自 Fedora 主机的文件内容:
$ curl -s http://localhost:8080/os-release
NAME="Fedora Linux"
VERSION="39 (Workstation Edition)"
ID=fedora
VERSION_ID=39
VERSION_CODENAME=""
...
我可以修改服务以将假os-release
文件绑定到该位置。首先,我创建/tmp/fake-osrelease
以下内容:
NAME="I reall am Ubuntu"
然后我BindReadOnlyPaths
向我的服务单元添加一个选项:
[Service]
Type=exec
ExecStart=/usr/sbin/darkhttpd /etc --port 8080
BindReadOnlyPaths=/tmp/fake-osrelease:/etc/os-release
现在,如果我重新加载系统并重新启动服务:
systemctl daemon-reload
systemctl restart fakeosrelease.service
当我检查文件时,我会看到虚假内容os-release
:
$ curl -s http://localhost:8080/os-release
NAME="I am really Ubuntu"
这个改变仅有的影响服务本身;如果我这样做,cat /etc/os-release
我仍然会看到原始内容。