A runlevel is a state of the system, indicating whether it is in the process of booting or rebooting or shutting down, or in single-user mode, or running normally. The traditional init program handles these actions by switching to the corresponding runlevel. Under Linux, the runlevels are by convention:
- S while booting,
- 0 while shutting down,
- 6 while rebooting,
- 1 in single-user mode and
- 2 through 5 in normal operation.
Runlevels 2 through 5 are known as multiuser runlevels since they allow multiple users to log in, unlike runlevel 1 which is intended for only the system administrator.
When the runlevel changes, init runs rc scripts (on systems with a traditional init — there are alternatives, such as Upstart and Systemd). These rc scripts typically start and stop system services, and are provided by the distribution.
/etc/rc.local is for use by the system administrator. It is traditionally executed after all the normal system services are started, at the end of the process of switching to a multiuser runlevel. You might use it to start a custom service, for example a server that’s installed in
/usr/local. Most installations don’t need
/etc/rc.local, it’s provided for the minority of cases where it’s needed.
rc denotes “run-control”,
multiuser runlevel would be defined as the level at which networking is available and thus connections to the server could be made using those services in lieu of hard-wired console connections.
Mind you, servers are generally managed by a service processor (under various names) which do support network connections and in turn act as if you indeed had a hard-wired console.
As for the
rc.local file, this is a convenience to allow you to specify all of the “local” (site-specific) objects (daemons and/or once-at-boot scripts) you want to start. You may choose to use this paradigm or actually populate ‘/etc/init.d’ with start/stop scripts, appropriately.
rc.local file on Debian is mostly for compatibility with non-init style systems. You should not use it.
Instead, it is recommended that you copy
/etc/init.d/Skeleton to a new init script for whatever you want to happen while changing runlevels, then use
inserv to enable it.
Update: As per the comment below, this answer is no longer recommended. However, this answer was posted several years before skeleton deprecation, and that skeleton still exists in Debian unstable as of January 2019.