When you install (or upgrade) a service, the package manager will try to
start (or restart) this service. If you are working on a normal server,
this is usually what you want. But if you are inside a
or maintaining some kind of golden image, you don’t want to start services.
If you are using Debian/Ubuntu-based distros, there is a super easy way
to solve the problem: the
Sysadmin inhibits service start and stop with this weird trick
When anything needs to start and stop services on Debian or Ubuntu, it
doesn’t invoke init scripts directly: it goes through
So, instead of doing
/etc/init.d/foobar start, a well-behaved
postinstall script should do
invoke-rc.d foobar start. It will
do exactly the same thing, except that it will run
start first. (If
/usr/sbin/policy-rc.d doesn’t exist, it is skipped.)
policy-rc.d script has only one job: it should tell to
if the action is allowed or not, by using its exit status. An exit status
0 means “action allowed”; an exit status of
101 means “action not
allowed”. There are other possibilities, for more complicated scenarios.
You can read the details in the invoke-rc.d interface documentation.
So, to prevent services from being started automatically when you install packages with dpkg, apt, etc., just do this (as root):
echo exit 101 > /usr/sbin/policy-rc.d chmod +x /usr/sbin/policy-rc.d
If you’re not root, you can use the
sudo tee trick, i.e.:
echo exit 101 | sudo tee /usr/sbin/policy-rc.d sudo chmod +x /usr/sbin/policy-rc.d
Why she got no bangs?
If you already knew about
policy-rc.d, here is a second chance to learn
something new today!
You might be wondering “shouldn’t I put
#!/bin/sh in the beginning of
the policy-rc.d script?”
If there is no shebang at the beginning of the file, the OS will try to
execute it as a “normal” binary. The
execve syscall will fail with
ENOEXEC (Exec format error). Well, unless your script happen to
conveniently have an ELF signature (or another binary signature recognized
by your system), but this is very unlikely.
What happens next depends on the calling program.
exec wrappers in the libc will try to use
/bin/sh as a fallback
to invoke the program – which is why I didn’t deem necessary to add a
shebang to the policy-rc.d script.
However, if you are running a shell, it will use
and if it fails, it will try to execute the script itself.
In other words, if you call a script without shebang from
bash will be used to execute it. (If the script is neither a standard
executable nor a bash script, major confusion will ensue.)
Note that in some languages,
execlp, and other
wrappers do not always call their libc counterparts. This is why in
Python (for instance), if you use
execvp on a script without a shebang,
you will get the
ENOEXEC error. It will not try to use
the normal libc call.
Isn’t that great? :-)