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?
5 Answers
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.
-
Not quite familiar with symlinks, can you elaborate with all the steps you take?– OxwiviNov 9, 2011 at 18:47
-
A symlink is a special type of file that has no content, instead it refers to another file (by path/name). They can be created with
ln -s
, in this case for exampleln -s /bin/true /root/fake/initctl
.– bseiboldNov 9, 2011 at 20:18 -
How does it prevent daemons from starting/restarting? According to @psusi's answer
invoke-rc.d
is responsible.– OxwiviNov 10, 2011 at 7:08 -
By placing the directory with the faked commands at the beginning of the
$PATH
variable, all calls toinvoke-rc.d
and others that can be used to start and stop daemons use the fake commands. That is, unless they are called with an absolute path, but I have never encountered this.– bseiboldNov 10, 2011 at 14:00 -
Ah, now I see how it works - basically, the symlinks leads to dead ends. But what exactly is the
/bin/true
thing? And what of the rest of the commands involved in the packages? Won't they get thrown off-track by the specified$PATH
?– OxwiviNov 10, 2011 at 14:07
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'm installing minimal Ubuntu on a drive, then instead of booting into it, I use a Live CD/USB to
chroot
and install the packages I need. Because of the things starting to run, sometimes I'm switched out of the ubuntu (live CD) session. Anyway, the thing I want to ask is, how do I use thisRUNLEVEL
inchroot
?– OxwiviNov 5, 2011 at 11:43 -
@Oxwivi, the same way, but it is supposed to automatically detect you are in a chroot and skip starting daemons.– psusiNov 7, 2011 at 14:43
-
Is it possible the buggy
invoke-rc.d
is responsible for the issues I faced?– OxwiviNov 7, 2011 at 15:24 -
@Oxwivi, it is possible, but more likely that a particular package is buggy and isn't using
invoke-rc.d
. What package was this?– psusiNov 7, 2011 at 15:29 -
1Nice idea, but it doesn't work for me.
sudo RUNLEVEL=1 apt-get install lighttpd
still fails withcan't bind to port: 80 Address already in use
Jun 11, 2013 at 15:54
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
-
4This is the proper solution but unfortunately, not complete. Firstly,
/usr/sbin/policy-rc.d
might already exist and this solution does not check for that. Secondly, other packages might ship their own/usr/bin/policy-rc.d
so you should dpkg-divert to protect against that. Lastly, by FHS policy you should not yourself put stuff into /usr/sbin. Instead the packages policy-rcd-declarative and policyrcd-script-zg2 will let you manage /usr/sbin/policy-rc.d in a declarative way.– joschMar 10, 2020 at 8:18
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 start-stop-daemon
and initctl
, so I followed suit.
A quick one-liner:
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
-
With regards to the person who put the "quick one-liner", you forgot to set /usr/sbin/policy-rc.d as executable. It'll be ignored otherwise.– user191809Sep 10, 2013 at 20:19
chroot
and install the packages I need. Of course drivers, specifically, GPU drivers are not there and needs to be installed.