Sometimes installing some applications will start a process or service from the application being run automatically on installation. How do I install without starting them?
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
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.
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
I believe you need to use the
--no-triggers command line option when you do the
dpkg install. Something like this:
dpkg -i --no-triggers SomeBigPackage.deb
To make this setting persistent so that
apt-get install does not run any triggers, create a custom dpkg configuration file in
# Install packages without starting background processes and services # See http://askubuntu.com/q/74061 no-triggers
Note that dpkg still logs triggers as having run even though they haven't:
$ sudo apt-get install redis-server … Starting redis-server: redis-server. $ service redis-server status redis-server is not running
Alternatively, you can have the installer script run the
service command to turn off the new service:
service name_of_service stop
What I ended up doing is emulating what debootstrap does when installing packages, except I used dpkg-divert:
First move the real files out of the way:
dpkg-divert --add --rename --local /sbin/start-stop-daemon dpkg-divert --add --rename --local /sbin/initctl
Then create dummy versions:
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"
Then do your apt-get upgrades, installs, etc., and then clean up with:
rm /sbin/initctl /sbin/start-stop-daemon dpkg-divert --remove --rename /sbin/initctl dpkg-divert --remove --rename /sbin/start-stop-daemon
I know there are other commands that can be used to stop/start services, but debootstrap only cares about
initctl, so I followed suit.