Three ways to create a startup script in Ubuntu
In this post, I will introduce three ways to create a startup script in Ubuntu: systemd (systemctl
command), cron job (@reboot
directive), and shell startup script (.bash_login
, .bashrc
, ...).
Suppose that the script to run is at /home/transang/startup.sh start
.
Method 1 (most reliable): Create a systemd startup service
Create a systemd unit file with .service
extension in /etc/systemd/system
, for example /etc/systemd/system/my-service.service
, with the following content.
[Unit]
Description=My custom startup script
[Service]
ExecStart=/home/transang/startup.sh start
[Install]
WantedBy=multi-user.target
You can now start/stop this service with systemctl start my-service
/ systemctl stop my-service
.
To enable this service when startup, run systemctl enable my-service
. Or to combine both enable
and start
with systemctl enable --now my-service
.
systemd unit file structure
Refer to this digital ocean post for more detail on the systemd unit file structure. Some useful configurations are described in comment format in the following configuration:
[Unit]
Description=My custom startup script
# After=network.target
# After=systemd-user-sessions.service
# After=network-online.target
[Service]
# User=spark
# Type=simple
# PIDFile=/run/my-service.pid
ExecStart=/home/transang/startup.sh start
# ExecReload=/home/transang/startup.sh reload
# ExecStop=/home/transang/startup.sh stop
# TimeoutSec=30
# Restart=on-failure
# RestartSec=30
# StartLimitInterval=350
# StartLimitBurst=10
[Install]
WantedBy=multi-user.target
Side-effect script
If your script has a side effect, you might want to clean the side effect when the service stops. A typical use case is to run a configuration script, unlike a service script that keeps running in the background. For example, configure an iptables
rule (check related post here).
You will need to define the cleaning script via ExecStop=/home/transang/startup.sh stop
and declare the service having side-effect via RemainAfterExit=yes
:
[Unit]
Description=My custom startup script
[Service]
ExecStart=/home/transang/startup.sh start
ExecStop=/home/transang/startup.sh stop
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Method 2 (unreliable): Add a startup cron job
Add a crontab line with the repeat section as @reboot
, i.e., run crontab -e
and append the following line to the opened file.
@reboot /home/transang/startup.sh
Nonetheless, this approach is not reliable. Not only is there a bug in some Debian variants, but the behavior of the @rebooot
cron job is also inconsistent between reboots and shutdowns/starts. Therefore, I will not discuss other perspectives such as when the @reboot
cron job gets executed, where it is stored, who the user is running it, or whether this cron job gets executed with a sudoer privilege.
Cron is not always installed by default in some Linux distributions (such as Arch Linux) and requires a manual installation.
Method 3 (inconsistent): Create a shell startup script
You can refer to this related post to read about startup scripts and their execution order.
A side note: after reading the post mentioned above, you will realize that it is unsure whether a bash startup script is executed, when it is executed (is it run before or after you log in to the graphical screen?).
This behavior also varies significantly on the graphical program (gnome, unity, kdm, .., etc.), even from version to version.