Home / Alt manpages / update-rc.d(8)

  • update-rc.d(8)
  • Admin command
  • linux

Manage SysV Init Links with update-rc.d

A service that keeps coming back after you disabled it is usually a SysV link problem, and update-rc.d controls those links.

These examples apply to the version installed here from init-system-helpers 1.66ubuntu1.

Allow about fifteen minutes. You need a shell, the service name, and a service script at /etc/init.d/SERVICE if you are creating links. Creating, disabling, enabling or removing links changes boot-time service behaviour, so use an administrative shell only once you have checked the name and intended runlevels.

Checkpoint

This tool manages links for System V style init scripts. It does not write a systemd unit and it does not replace the service script itself.

1. Check the installed command and service name

Confirm which command will run and record the package version. These are ordinary, read-only checks:

$ command -v update-rc.d
/usr/sbin/update-rc.d
$ dpkg-query -W -f='${Package} ${Version}\n' init-system-helpers
init-system-helpers 1.66ubuntu1
$ update-rc.d --help
usage: update-rc.d [-f] <basename> remove
       update-rc.d [-f] <basename> defaults
       update-rc.d [-f] <basename> defaults-disabled
       update-rc.d <basename> disable|enable [S|2|3|4|5]

Replace SERVICE below with the basename of the script, not its full path: for /etc/init.d/warehouse-api, use warehouse-api. Check the exact path before changing anything:

$ test -f /etc/init.d/SERVICE && echo "script exists"
script exists
$ find /etc/rc*.d -maxdepth 1 -type l -name '[SK][0-9][0-9]SERVICE' -printf '%p -> %l\n'

An empty second command is fine: it just means there are no matching links yet. Do not continue with a guessed service name.

defaults takes dependency and runlevel information from the LSB comment header in the init script. Inspect that header as the administrator who will run the change:

$ sed -n '/^### BEGIN INIT INFO/,/^### END INIT INFO/p' /etc/init.d/SERVICE
### BEGIN INIT INFO
# Provides:          SERVICE
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Should-Start:      $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: example service
### END INIT INFO

That is a shape to compare against your file, not a header to paste blindly. If it is missing or wrong, fix the package or service definition first: the link generator cannot infer safe dependencies from the service name alone.

Warning

This changes what the init system can start during runlevel changes. Review the script and header first, then run with elevated privileges:

$ sudo update-rc.d SERVICE defaults

The normal result is no output. Links appear under directories such as /etc/rc2.d/ and /etc/rc6.d/, pointing back to /etc/init.d/SERVICE. The two-digit part controls ordering; the exact numbers come from dependency and runlevel handling on this host, so inspect rather than assume a value.

  • Existing links win. If matching S or K links already exist, update-rc.d leaves them alone, so rerunning defaults is not a general way to repair hand-edited links.

Checkpoint

Verify the links and their targets:

$ find /etc/rc*.d -maxdepth 1 -type l -name '[SK][0-9][0-9]SERVICE' -printf '%p -> %l\n'
/etc/rc2.d/S##SERVICE -> ../init.d/SERVICE
/etc/rc6.d/K##SERVICE -> ../init.d/SERVICE

The sequence numbers and full list vary with the script header and installed init tooling. A symlink pointing at another script, or a link in an unexpected runlevel, needs investigating before you start the service.

To stop a service starting through these SysV links, use disable. This is a state change and normally needs elevated privileges:

$ sudo update-rc.d SERVICE disable

The command renames start links in runlevels S, 2, 3, 4 and 5 into stop links. Its sequence calculation uses 100 - old number, so a start link such as S20SERVICE becomes a stop link with the corresponding calculated number. It does not remove the links or delete the init script.

To limit the operation to one start runlevel, give it as the final argument:

$ sudo update-rc.d SERVICE disable 2

Verify the result, remembering that host-specific link names are expected:

$ find /etc/rc*.d -maxdepth 1 -type l -name '[SK][0-9][0-9]SERVICE' -printf '%p -> %l\n'

Use enable to undo this:

$ sudo update-rc.d SERVICE enable

It renames stop links back to start links using the inverse calculation. The installed command warns that its disable/enable API is not stable, so do not build a long-lived automation contract around the undocumented numbering.

5. Create a disabled installation when that is the intended default

For a script that should be installed but not started by default, use defaults-disabled:

$ sudo update-rc.d SERVICE defaults-disabled

This creates stop links using dependency information from the LSB header. It differs from removing every link: the package can recognise the service was deliberately disabled, and a later upgrade is less likely to treat it as never configured.

Check the result with the same find command from step 3. If matching links already existed, the preserve-existing-links rule applies and this command will not overwrite that configuration.

remove is for a script that has already been deleted, commonly during package purge. It removes matching links but leaves unrelated files alone:

$ sudo rm /etc/init.d/SERVICE
$ sudo update-rc.d SERVICE remove

Warning

Deleting an init script is irreversible unless you have a verified backup or package reinstall path. Do not use this as a synonym for disable. If the script still exists, the command refuses to remove the links; -f overrides that safety check:

$ sudo update-rc.d -f SERVICE remove

Use -f only when you have deliberately confirmed every matching link should go. Recovery is to restore /etc/init.d/SERVICE from the owning package or backup, then recreate links with the correct header and defaults or defaults-disabled.

Common traps

  • Deleting links to "disable" a service. If no links remain, a package's post-install script may run update-rc.d and install the factory defaults again during an upgrade. Use disable, or install deliberately with defaults-disabled, and record the reason in your change notes.
  • Assuming empty links mean nothing can start. These commands manage boot-time links only. A service may still be started manually, by another supervisor, or by a separate systemd unit, so check the actual service manager before treating a disabled link set as proof of anything.

Done means

  • Version checked. You confirmed the installed version and used the service basename.
  • Header matches. The init script exists and its LSB header matches the intended runlevels.
  • Links inspected. You checked links after every state-changing command.
  • Disable, not delete. You used disable rather than deleting links to keep a service off.
  • Remove reserved. You kept remove and -f for deliberate script removal or purge work.
  • Recovery known. You know how to restore the script and recreate its links if needed.