update-rc.d disable/remove will not remove etc/init.d/rc* references
Categories:
Understanding update-rc.d: Why 'disable' Doesn't Always Remove etc/init.d/rc* References

Explore the nuances of update-rc.d
on Debian-based systems, focusing on why disabling or removing a service doesn't always clear all runlevel symlinks and how to manage them effectively.
On Debian-based Linux distributions, update-rc.d
is a crucial utility for managing System V init script links in the /etc/rcN.d/
directories. These links determine which services start or stop at different runlevels. While update-rc.d
provides options like disable
and remove
, their behavior regarding the actual removal of symlinks can sometimes be counter-intuitive, leading to confusion about service management. This article delves into the specifics of update-rc.d
and clarifies how to ensure services are properly managed across runlevels.
The Role of update-rc.d and Runlevels
Linux systems, particularly those using System V init (like older Debian/Ubuntu versions, though systemd
is now prevalent, update-rc.d
still manages compatibility for init.d
scripts), utilize runlevels to define the state of the system. Each runlevel (e.g., 0 for halt, 1 for single-user mode, 2-5 for multi-user modes, 6 for reboot) has a corresponding directory (/etc/rc0.d/
, /etc/rc1.d/
, etc.) containing symbolic links to scripts in /etc/init.d/
. These links are prefixed with 'S' for start and 'K' for kill (stop), followed by a two-digit priority number and the script name. update-rc.d
is designed to manage these symlinks.
flowchart TD A[System Boot] --> B{Init Process Starts} B --> C{Determine Runlevel} C --> D[Execute K-scripts in /etc/rcN.d/] D --> E[Execute S-scripts in /etc/rcN.d/] E --> F[System Ready]
Simplified Linux Boot Process with Runlevels
Understanding 'disable' vs. 'remove'
The update-rc.d
command offers several actions, but disable
and remove
are often misunderstood.
update-rc.d <script> disable
: This command typically renames the 'S' (start) links to 'K' (kill) links in the default runlevels, effectively preventing the service from starting automatically. It does not delete the links entirely. The service can still be manually started or stopped. The original 'S' links are replaced by 'K' links with a high kill priority (e.g., K01).update-rc.d <script> remove
: This command is intended to remove all symbolic links for the specified script from all/etc/rcN.d/
directories. However, it only works if the script is not currently configured to start at any runlevel (i.e., if it has already been 'disabled' or never enabled). If 'S' links still exist,remove
might fail or only remove 'K' links, leaving 'S' links intact. This behavior can be confusing.
update-rc.d remove
. If the service is still enabled (has 'S' links), remove
might not fully clear all references, potentially leading to unexpected service startups. Always verify the state of the /etc/rcN.d/
directories after running the command.The 'Defaults' and 'Force' Options
When update-rc.d
is used with defaults
, it creates 'S' links in runlevels 2, 3, 4, 5 and 'K' links in runlevels 0, 1, 6. This is the standard way to enable a service. The force
option can be used to override certain checks, but it should be used with extreme care as it can lead to an inconsistent state.
To truly remove all links, a common pattern is to first disable the service, then remove it. However, even this sequence can sometimes leave remnants if the script was not initially set up with defaults
or if manual links were created.
# Enable a service with default runlevels
sudo update-rc.d my_service defaults
# Disable a service (converts S links to K links)
sudo update-rc.d my_service disable
# Attempt to remove all links (might require prior disable)
sudo update-rc.d my_service remove
# Verify remaining links (should be empty if successful)
ls -l /etc/rc*.d/*my_service*
Common update-rc.d
commands for service management
systemd
, the preferred method for managing services is systemctl
. While update-rc.d
still functions for init.d
scripts, systemctl disable <service>
and systemctl stop <service>
are generally more reliable and recommended.1. Check Current Service Status
Before making changes, inspect the current state of your service's symlinks across runlevels. This helps you understand what update-rc.d
will be acting upon.
2. Disable the Service Gracefully
Use sudo update-rc.d <script_name> disable
to convert 'S' links to 'K' links. This prevents the service from starting automatically on subsequent reboots without fully removing its configuration.
3. Remove All Symlinks
After disabling, execute sudo update-rc.d <script_name> remove
. This command should now successfully remove all 'K' links (and any remaining 'S' links if the disable step was effective).
4. Verify Removal
Manually check the /etc/rcN.d/
directories using ls -l /etc/rc*.d/*<script_name>*
to ensure no symlinks remain. If any are found, they might be manual additions or remnants from an unusual configuration.
5. Consider systemctl for Modern Systems
If your system uses systemd
, use sudo systemctl disable <service_name>
and sudo systemctl stop <service_name>
for more robust and integrated service management.