1. Overview
In this tutorial, we’ll see how we can run a command or a script when a Linux system starts up. We’ll cover different methods using the rc.local file, cron jobs, and systemd services.
2. Classic Approach: rc.local File
When we boot up a machine running Linux, the first process that runs is the init process. The init process runs certain scripts based on the state in which the machine is currently. These states are known as runlevels. During each run level, a series of rc scripts are executed to make the system ready for usage or a shutdown.
The rc.local script file should be available on most UNIX operating systems. However, we should know that it might not be available, by default, on modern Linux distributions. So, we’ll have to configure it manually. The rc.local script will run with system administrator privileges. Therefore, it’s easier to run a script or a command as root.
2.1. Usage
Let’s add a simple command to the script that we’d like to execute once the system starts up:
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Ensure that the script will "exit 0" on success or any other
# value on error.
#
# To enable or disable this script, just change the execution
# bits.
#
# By default, this script does nothing.
pgrep -x $(teamviewerd) || teamviewerd
exit 0
In the script, we added a line to run the teamviewerd daemon once the system starts up. Mind that commands that come after exit 0 will not execute. Sometimes, the commands inside the script will not run even if they are correct. In that case, we should check for execution permissions of the file and modify them accordingly.
2.2. Enabling rc-local Service on Modern Linux Distributions
Most mainstream Linux distros use systemd as its init and service managers. systemd has its own way of executing custom scripts on start-up. Nevertheless, we can still create a simple “rc-local” systemd process that will enable us to run the rc.local script on start-up.
Create a new file in the /etc/systemd/system/rc-local.service and put the following contents in the file:
[Unit]
Description=/etc/rc.local Compatibility
ConditionPathExists=/etc/rc.local
[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
StandardOutput=tty
RemainAfterExit=yes
SysVStartPriority=99
[Install]
WantedBy=multi-user.target
Once we save the file, we should enable this service using systemctl:
$ systemctl enable rc.local
After enabling the service, we’d need to create the rc.local file and give it the appropriate permissions.
3. Alternative: Cron Job
A crontab is a file that contains a list of commands that can be scheduled to run periodically. The tasks that we specify in this file are cron jobs. Typically, they are run by a cron daemon, which is installed on most distributions.
There are different cron programs, which all work the same way and use a similar crontab format. It’s up to us to choose one and configure it.
3.1. Installation
There might be cases where we don’t have a cron program installed on our server if it’s running distributions like Gentoo. Therefore, we’d need to install it and configure it manually. We’ll install the lightweight cron utility known as cronie. It’s available on most repositories under the name cronie, which we can install using a package manager.
On Ubuntu and Debian, we can use apt:
# apt install cronie
For Fedora and RHEL, we can use yum:
# yum install cronie
Once the installation is complete, go ahead and verify it:
$ crond -V
cronie 1.5.7
Now, we need to enable the crond service, which is basically the daemon that will run when the system boots up:
# systemctl enable crond
Now, we’re ready to schedule cron jobs in the crontab.
3.2. Usage
A simple crontab can consist of one or more lines. Each line corresponds to a task that is carried out periodically. Let’s create a crontab with the crontab command:
$ crontab -e
At first, it should be an empty file. Let’s add a couple of tasks, which are run each time the system starts up:
@reboot pulseaudio -k && pulseaudio
@reboot redshift -c ~/.config/redshift/config.conf
A crontab entry consists of two fields — the time field and the command field. The time field specifies when to run the corresponding command. In this crontab, we added @reboot, which signifies that we want to run the commands once the system starts up.
We should know that the above commands will be executed as normal users. The -e option tells crontab to edit the current user’s crontab. If we want to run commands as root, we should run the crontab command as root, which will create another crontab file for the root user.
Let’s create a task that executes a shell script as root on start-up:
$ sudo crontab -e
@reboot . /root/upgrade-system.sh
4. Alternative: systemd
systemd is not just a service manager and an init system but rather a complete collection of utilities that carry out most of the tasks on Linux distributions.
Before systemd, we’d need to use different tools for different purposes, which in some cases were not as effective as systemd. These days, systemd is a part of every popular Linux distribution such as Fedora, Ubuntu, Mint, Debian, and so on. Therefore, we should use it instead of relying on external tools.
4.1. Creating the Start-Up Script
First, we need a script file that contains the command(s) that we’d like to run on start-up. Later, we’ll specify this file to run in a custom systemd service. So, let’s create a script file that basically starts a notification daemon:
pgrep dunst || setsid -f dunst
Be sure to make this script executable.
4.2. Creating a systemd Service
Now that our script is ready, we need to create a systemd service that sources our script file. So, let’s go ahead and create a startup.service file inside /lib/systemd/system:
$ touch /lib/systemd/system/startup.service
Now, let’s define our service in this file:
[Unit]
Description=Startup Script
[Service]
ExecStart=/root/.local/bin/startup.sh
[Install]
WantedBy=multi-user.target
We can modify the ExecStart field to specify the path to our start-up script. Once done, save the file and enable this service so it would run each time our machine boots:
# systemctl enable startup.service --now
systemd will enable this service and run it immediately because we’ve added the –now option.
In the same way, we can create multiple services to run on start-up for different purposes.
5. Conclusion
In this tutorial, we saw how we can run Linux commands and scripts on start-up. We covered three different methods that we can use in different environments.