The core idea of sysvinit is something called runlevels, which are essentially just a way of organizing a collection of init scripts which have to run when the system starts or shuts down. Each runlevel corresponds to a directory in /etc/
, which in turn contains symlinks to scripts in /etc/init.d/
.
For historical reasons, there are a lot of runlevels, but a bunch of them aren't really used for anything special on Debian systems. You can read the full details of this in the Debian manual, but the short version is that the system normally boots to runlevel 2, which is multi-user mode. Adapted from the manual, here's a partial table of levels:
runlevel |
directory |
usage |
N |
System boot. |
|
0 |
/etc/rc0.d/ |
Halt the system. |
1 |
/etc/rc1.d/ |
Single user mode (if you switch from multi-user mode). |
2 |
/etc/rc2.d/ |
Multi-user mode. |
3 - 5 |
/etc/rc3.d through /etc/rc5.d/ |
Identical to runlevel 2 (unless you do something funny with your system). |
6 |
/etc/rc6.d/ |
Reboot the system. |
Let's get a list of what's in runlevel 2:
cd /etc/rc2.d/ ls -l
ls -l
gives a long listing of files, which will helpfully show you if a file is really a link to another file. Again, all of the actual init scripts turn out to live in /etc/init.d
.
If a file in /etc/rc*.d/
starts with K
, it will be invoked by the init system with [name of script] stop
(K is for kill), and if it starts with S
, it will be invoked with [name of script] start
.
Init scripts usually accept (most of) the following command-line parameters:
-
start
- start the service -
stop
- stop the service -
status
- check whether the service is running -
reload
- have the service reload configuration files -
restart
- stop and start the service
So, for example, you could say /etc/init.d/ssh restart
to stop and start the SSH service. You often see commands like this in tutorials and HOWTOs.
As an example, load up /etc/init.d/ssh
in a text editor and give it a look.
cd /etc/init.d nano ssh
This is actually quite a few lines of code for what seems like a pretty simple task - it just needs to start or stop a program, right? It turns out, though, that there can be a lot of considerations involved in doing that. For example, these rather squirrelly-looking lines...
test -x /usr/sbin/sshd || exit 0 ( /usr/sbin/sshd -\? 2>&1 | grep -q OpenSSH ) 2>/dev/null || exit 0
...make sure that sshd
exists, is executable, and at least claims to be the SSH daemon provided by the OpenSSH project. The rest of the script defines functions for all sorts of housekeeping and sanity checks before it gets to the part where it handles the start/stop/etc. commands in a case statement:
case "$1" in start) check_privsep_dir check_for_no_start check_dev_null log_daemon_msg "Starting OpenBSD Secure Shell server" "sshd" || true if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then log_end_msg 0 || true else log_end_msg 1 || true fi ;; stop) log_daemon_msg "Stopping OpenBSD Secure Shell server" "sshd" || true if start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/sshd.pid; then log_end_msg 0 || true else log_end_msg 1 || true fi ;; # a whole bunch of other stuff happens here esac
For one-off projects on the Pi, you almost certainly don't need to exercise this level of caution, but you will want to handle the common commands.
It would be a pain to write a lot of this stuff out from scratch. Fortunately, we have /etc/init.d/skeleton
to work with. This just provides the "bones" of an init script, and should work with a few minor changes. Next, we'll look at adapting it to run our example mouse.py
.
Page last edited August 27, 2015
Text editor powered by tinymce.