在不启动后台进程和服务的情况下安装软件包


43

有时,安装某些应用程序会从安装时自动运行的应用程序启动进程或服务。我如何不启动就安装它们?


我不知道在使用这种配置安装内核或DKMS软件包时,使系统处于不稳定状态的潜力是什么。我对这方面了解不多。
ændrük

@ændrük这让我担心。您会看到我在驱动器上安装了最小的Ubuntu,然后使用Live CD / USB来chroot安装我需要的软件包,而不是启动它。当然,具体来说,驱动程序不存在,需要安装GPU驱动程序。
Oxwivi 2011年

Answers:


35

在自动安装脚本中有一段时间,我已经使用了一种有点骇人听闻但相当可靠的方式来执行此操作。

首先创建一个目录,例如/root/fake,其中包含指向的符号链接/bin/true

initctl
invoke-rc.d
restart
start
stop
start-stop-daemon
service
deb-systemd-helper

您还可以使它们成为不执行任何操作并返回成功的bash脚本。

然后$PATH在安装软件包时在最前面添加该目录:

PATH=/root/fake:$PATH apt-get install whatever

这只会阻止守护程序启动/重新启动,而诸如创建initramfs之类的事情仍在进行中。

说明

在软件包安装和删除时执行的脚本会执行invoke-rc.d上述命令或其他命令以启动和停止服务。但是,它们不会使用绝对路径来调用它们(至少我没有遇到过绝对路径)。

因此,通过在的开头插入伪造的“ no operation”命令,将$PATH永远不会调用实际命令。

由于仅用于启动/停止服务的命令是伪造的,因此其他所有内容,特别是重要任务,如更新/创建initramfs-images,仍然有效。


对符号链接不太熟悉,您能否详细说明所有步骤?
Oxwivi

符号链接是一种特殊的文件,没有内容,而是引用另一个文件(按路径/名称)。ln -s例如,可以使用创建它们ln -s /bin/true /root/fake/initctl
bseibold 2011年

如何阻止守护程序启动/重新启动?根据@psusi的回答invoke-rc.d负责。
Oxwivi

通过将带有伪造命令的目录放置在$PATH变量的开头,所有invoke-rc.d可用于启动和停止守护程序的调用和其他调用都将使用伪造命令。也就是说,除非使用绝对路径调用它们,但我从未遇到过。
bseibold 2011年

嗯,现在我知道它是如何工作的-基本上,符号链接导致死胡同。但是到底是什么/bin/true东西?软件包中涉及的其余命令又是什么?他们会不会被指定的轨道丢掉$PATH
Oxwivi 2011年

27

后台守护程序以开头invoke-rc.d,如果该守护程序的rc脚本表明不应在当前系统运行级别上运行,则确保该守护程序未启动。您可以通过设置环境变量RUNLEVEL来覆盖其对当前系统运行级别的想法。不应在运行级别0和6上运行任何内容,但是invoke-rc.d如果使用这些运行级别,则似乎有问题并且可以运行任何东西。大多数守护程序不在运行级别1中运行,因此您可以像这样阻止它们在安装时启动:

sudo RUNLEVEL=1 apt-get install redis-server

我在驱动器上安装了最小的Ubuntu,然后使用Live CD / USB来chroot安装所需的软件包,而不是启动该驱动器。由于事情开始运行,有时我会退出ubuntu(实时CD)会话。无论如何,我要问的是,我怎么用这个RUNLEVELchroot
Oxwivi

@Oxwivi,以相同的方式,但是应该可以自动检测到您在chroot中,并跳过启动守护程序。
psusi 2011年

越野车是否可能invoke-rc.d是我遇到的问题的原因?
Oxwivi 2011年

@Oxwivi,有可能,但更可能是某个特定的程序包有错误并且没有使用invoke-rc.d。这是什么包?
psusi 2011年

我不知道,我只是列出了所有要安装的软件包,也不介意终端进一步查看输出。
Oxwivi 2011年


5

我相信您--no-triggersdpkg安装时需要使用命令行选项。像这样:

dpkg -i --no-triggers SomeBigPackage.deb

要使此设置持久化,使其apt-get install不运行任何触发器,请在以下位置创建一个自定义dpkg配置文件/etc/dpkg/dpkg.cfg.d/custom

# Install packages without starting background processes and services
# See http://askubuntu.com/q/74061  
no-triggers

请注意,即使dpkg触发器没有运行,它仍然会将其记录为已运行:

$ sudo apt-get install redis-server 
…
Starting redis-server: redis-server.
$ service redis-server status
redis-server is not running

或者,您可以让安装程序脚本运行service命令以关闭新服务:

service name_of_service stop

1
任何apt-get等效的?还是有一种方法可以配置dpkg为直接--no-triggers使用dpkg还是apt-get安装某些东西来运行?
Oxwivi

dan_linder,希望您不要介意我对@Oxwivi问题的回答进行编辑。如果您不喜欢它,请随意对其进行修改/还原。
ændrük

5
这是不正确的。触发器与启动守护程序无关。触发器是一个程序包,它执行一些操作以响应另一个响应程序来重新配置自身,例如,如果您安装了一个添加了initramfs挂钩的程序包,它将触发initramfs-tools程序包来重建您的initramfs。
psusi 2011年

3

我最终要做的是模拟安装软件包时的debootstrap行为,除了我使用dpkg-divert之外:

首先将实际文件移开:

dpkg-divert --add --rename --local /sbin/start-stop-daemon
dpkg-divert --add --rename --local /sbin/initctl

然后创建虚拟版本:

echo \
"#!/bin/sh
echo
echo \"Warning: Fake start-stop-daemon called, doing nothing\"" > "/sbin/start-stop-daemon"
chmod 755 "/sbin/start-stop-daemon"

echo \
"#!/bin/sh
echo
echo \"Warning: Fake initctl called, doing nothing\"" > "/sbin/initctl"
chmod 755 "/sbin/initctl"

然后进行apt-get升级,安装等,然后使用以下方法进行清理:

rm /sbin/initctl /sbin/start-stop-daemon
dpkg-divert --remove --rename /sbin/initctl
dpkg-divert --remove --rename /sbin/start-stop-daemon

我知道还有其他命令可用于停止/启动服务,但是debootstrap只关心start-stop-daemoninitctl,所以我也照做。


3

快速的单线:

echo -e '#!/bin/sh\nexit 101' | install -m 755 /dev/stdin /usr/sbin/policy-rc.d && apt-get install **Package** && rm -f /usr/sbin/policy-rc.d

关于放置“快速单线”的人,您忘记将/usr/sbin/policy-rc.d设置为可执行文件。否则将被忽略。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.