Install packages without starting background processes and services

There's a slightly hackish, but quite reliable way to do this which I've been using for a while in an automated installation script.

First create a directory, for example /root/fake, which contains symlinks to /bin/true called:

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

You could also make them bash scripts that do nothing and return success.

Then include that directory at the front of $PATH when installing packages:

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

This only prevents daemons from starting/restarting, while things like creating an initramfs are still being done.

Explanation

The scripts which are being executed at package installation and removal execute invoke-rc.d or others of the mentioned commands to start and stop services. They don't however call them with absolute paths (at least I haven't encountered one that does).

So by inserting the faked "no operation" commands at the beginning of $PATH, the real commands never get called.

Since only the commands used to start/stop services are being faked, everything else, in particular important tasks like updating/creating initramfs-images still work.


Background daemons are started with invoke-rc.d, which makes sure that the daemon is not started if its rc script says it is not supposed to run in the current system runlevel. You can override its idea of the current system runlevel by setting the environment variable RUNLEVEL. Nothing is supposed to run in runlevels 0 and 6, but it appears that invoke-rc.d is buggy and runs things anyhow if you use these runlevels. Most daemons do not run in runlevel 1, so you can prevent them from being started on install like this:

sudo RUNLEVEL=1 apt-get install redis-server

There is a better solution:

cat > /usr/sbin/policy-rc.d <<EOF
#!/bin/sh
exit 101
EOF
chmod a+x /usr/sbin/policy-rc.d

Tags:

Apt