1. Overview
In this quick tutorial, we’ll explore different options for executing a script on startup in Linux. This comes in handy in plenty of situations, such as if we want to start a server application automatically.
2. Solutions
Without further ado, let’s create a simple script to execute:
#!/bin/sh
echo "Last reboot time: $(date)" > /etc/motd
This piece of code sets the message of the day to be the last reboot time, so that each user can see it after their first login.
Then we’ll save our file and make it executable:
$ chmod +x reboot_message.sh
Now that our script is ready, let’s see how to schedule its execution.
2.1. Using cron
Let’s begin with the easiest solution, which involves using cron. In order to do this, we need to edit our crontab file:
$ crontab -e
Here we’ll add a line using the @reboot expression, which will execute our code once at startup:
@reboot sh /home/ec2-user/reboot_message.sh
This solution is quick and clean, since we don’t have to deal with additional configuration, but not every version of cron supports @reboot.
2.2. Using rc.local
Now let’s consider another solution that takes advantage of the /etc/rc.d/rc.local file. Since this file already runs at startup, we can append a line that invokes our script:
sh /home/ec2-user/reboot_message.sh
In order for this to work, we need to ensure that the rc.local file itself is executable:
$ chmod +x /etc/rc.d/rc.local
2.3. Using init.d
Similar to the previous solution, the /etc/init.d folder contains lifecycle executables of the services managed by the system. We can also add our own by creating an LSB-compliant wrapper that starts our service:
#! /bin/sh
# chkconfig: 345 99 10
case "$1" in
start)
# Executes our script
sudo sh /home/ec2-user/reboot_message.sh
;;
*)
;;
esac
exit 0
This wrapper will launch our code when it’s invoked with the start argument. However, we must include a line with the chkconfig configuration, which contains the service runlevel and the start/stop priority.
After placing the wrapper in the init.d folder, we need to register our service for startup execution:
$ chkconfig --add service_wrapper.sh
Since the chkconfig command isn’t available on Debian systems, update-rc.d can be used as an alternative there:
$ update-rc.d service_wrapper.sh defaults
2.4. Using systemd
Finally, let’s see how to run a script with systemd. Similar to init.d, we need to create a service descriptor, called a unit file, under /etc/systemd/system:
[Unit]
Description=Reboot message systemd service.
[Service]
Type=simple
ExecStart=/bin/bash /home/ec2-user/reboot_message.sh
[Install]
WantedBy=multi-user.target
The file is organized into different sections:
- Unit – contains general metadata, like a human-readable description
- Service – describes the process and daemonizing behavior, along with the command to start the service
- Install – enables the service to run at startup using the folder specified in WantedBy to handle dependencies
Next, we’ll need to set the file permissions to 644, and enable our service by using systemctl:
$ chmod 644 /etc/systemd/system/reboot_message.service
$ systemctl enable reboot_message.service
One thing to keep in mind is that, although many major distributions support systemd, it’s not always available.
3. Conclusion
In this article, we took a look at different ways of executing a script at startup in Linux. Each one of them has its pros and cons, but generally speaking, systemd and cron should be preferred when available. Consequently, rc.local and init.d should be used as fallbacks.