Some operating systems come with SysVinit as the service manager, instead of Systemd. Here I will teach you how to run scripts at boot using this tool.

I am going to use MX Linux, a Debian based distro with sysVinit installed.

Table of Contents

Runlevels

A runlevel is one of the modes that a UNIX-based system can run. Each runlevel has certain number of services to be running, so the user can control the behaviour of the system by adding or removing services on each runlevel, or changing the default runlevel. Most systems have seven runlevels.

MX Linux Runlevel Comment
0 Halt the system.
1 Single-user mode: provides a root console without logon. Useful if you lose your root password.
2 Multiuser with no network.
3 Console logon, no X (i.e. no GUI).
4 Not used/custom
5 Default GUI logon
6 Reboot the system

You can check the runlevel you are on by typing runlevel on a Terminal.

Init scripts

init is the parent process of all system processes (its Process ID is 1). When system boots, init process is started and executes all startup scripts inside /etc/rc?.d/ (? is the runlevel). MX Linux default runlevel is 5, so init will execute scripts inside /etc/rc5.d/. Default runlevel is specified on /etc/inittab:

id:5:initdefault:

Inside each rc?.d folder, there are symbolic links to files inside /etc/init.d/.

Changing a runlevel

You can change the runlevel at boot time of when the system is running. For example, if you want to change to a console runlevel (no GUI):

  • From the GRUB menu: type e (for ‘edit’) when your operating system is selected, go to the end of the line that starts with linux /boot/vmlinux-5..., add a space and type the runlevel number (e.g.: 3). Finally, press F10 to boot.

GRUB menu

  • From the desktop: press Ctrl + Alt + F1 to get out of X. Log in as root and run telinit 3.

Writing rc.d scripts

As I said before, init scripts are inside /etc/init.d/.

$ ls -l /etc/rc5.d/
total 0
lrwxrwxrwx 1 root root 14 Mar  3 18:31 K01nmbd -> ../init.d/nmbd
lrwxrwxrwx 1 root root 14 Mar  3 18:31 K01smbd -> ../init.d/smbd

Scripts start with the ‘shebang’, a line that indicates which shell to use to execute the script:

#!/bin/sh

After that line, there is a section for the init information:

### BEGIN INIT INFO
# Provides:          anacron
# Required-Start:    $remote_fs $syslog $time
# Required-Stop:     $remote_fs $syslog $time
# Default-Start:     2 3 4 5
# Default-Stop:
# Short-Description: Run anacron jobs
# Description: The first purpose of this script is to run anacron at
#              boot so that it can catch up with missed jobs.  Note
#              (truncated output)
### END INIT INFO

Run man insserv for more info about this comment header.

After this section goes the script commands. After creating your script, you need to create a symbolic link to /etc/rc<runlevel>.d/ by running update-rc.d <script name> defaults (run man update-rc.d for more info on this command).

Example

I am going to create a basic script to show how they work (run all commands as root):

  • Create a file inside /etc/init.d:
      nano /etc/init.d/test-init
    
  • Add this content to the file:
      #!/bin/sh
    
      ### BEGIN INIT INFO
      # Provides:          echo
      # Required-Start:
      # Required-Stop:
      # Default-Start:     2 3 4 5
      # Default-Stop:
      # Short-Description: Appends a line on a file
      # Description:       Creates a file if it does not exist
      #                    and appends a line
      ### END INIT INFO
    
      case "$1" in
      start)
          echo "Service started: `date`" >> /root/testfile
          ;;
      stop)
          echo "Service stopped: `date`" >> /root/testfile
          ;;
      esac
    
      exit 0
    
  • Create a symbolic link to /etc/rc<runlevel>.d/
      update-rc.d test-init defaults
    
  • Reboot and check if the file has been created:
      # cat /root/testfile
      Service started: Sun Jul 10 17:52:46 CEST 2022
    

OpenRC

OpenRC is another init system, maintained by Gentoo developers. Its usage is very similar to sysVinit, scripts are compatible and are located in the same /etc/init.d/ path and update-rc.d command is also available.

If you have any suggestion, feel free to contact me via social media or email.