Running custom scripts on startup is a common operation in the Linux community. In my case, when the machine hosting my website needs to be rebooted or even crashes, it is critical that the backend processes that the website depends on start correctly. For other Linux or BSD users, it can be useful to start up useful background processes, perhaps servers for accessing your machine remotely.

The Classic Method for Running Processes at Startup

The most documented way of starting processes when the machine boots is to add a control script to /etc/init.d. This script must take an argument that can be one of “stop,” “start,” and “restart.” An example of such a script would be /etc/init.d/ssh, which is used to start and stop the ssh server. When a machine shuts down, it is important for many daemons to clean up their pid files and otherwise shut down nicely. However, for user-run processes, simply being sent SIGTERM as part of normal shutdown is sufficient.

Here is an example of a script that is used only for starting a process.

To ensure that daemons are started and stopped, particularly in the correct order, the machine runs special symlinks to these scripts. The symlinks have special names that either begin with an S or a K. For example, my machine has /etc/rc3.d/S20lighttpd and /etc/rc0.d/K20lighttpd. (The numbers in the rc directory names are known as runlevels. A discussion of runlevels is beyond the scope of this article, and if you wish to know more, there are a number of good resources on the internet.) Scripts beginning with S are used to start a process during bootup. Those beginning with K are used to kill a process during shutdown. The number in the link name is used to determine the order in which these processes are started and killed.

Thus, to run a process at startup on your Linux machine, you would need to both add a script to /etc/init.d that takes “start” as an argument, and you would want to add symlinks to your script to the /etc/rc*.d directories. Your scripts have to follow the naming convention described above, probably starting with S99 or S98 to ensure that your processes start after all the important system daemons. The K symlink is unnecessary.

Using /etc/rc.local – A Better Way to Start Processes on Debian and Ubuntu

Instead of adding a startup script and the related symlinks, a much easier approach is to add your commands to the bash script /etc/rc.local. A quick look at /etc/rc.local demonstrates that it is rather self-explanatory.

$ cat /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
exit 0

At the end of /etc/rc.local, but before the exit 0 line, I can simply add a call to my server startup script:

# Run website processes
/home/prod/start_server.sh

It is a one-line change, instead of adding an overly complicated script and the related symlinks. Of course, this is not an option if you require additional commands to be run at shutdown. In addition, if you need your process to be started before some other system process, you must resort to the classic startup script as discussed above. /etc/rc.local almost the last script to be run as part of the boot process.

Conclusion: Use /etc/rc.local to Run Processes at Startup in Linux

Classic startup scripts in /etc/init.d and /etc/rc*.d are appropriate for many daemons and some more complicated user processes that must either start before a system process or be cleaned up during shutdown. However, /etc/rc.local is preferred for all other cases. It is a simple bash script you can edit as root on your machine.

By default, there is no rc.local on debian-based distros (unless soemthing has changed recently), but there are a lot of tutorials on the web for creating an equivalent to rc.local (like redhat-based distro have always had).

I keep seeing comments that Debian distros do not have rc,local, but Debian 6 and I believe 5 both have rc.local installed under /etc/ by default, Having it installed or not may depend on user selectable install options, but I’ve done plenty of minimal installations and it always shows up.