The Modern Approach to Linux Boot Scripts
In the early days of Linux, if a system administrator wanted to execute a custom bash script automatically every time the server booted up, they would simply paste the command into a file called /etc/rc.local. It was incredibly simple, but it was also messy, difficult to troubleshoot, and provided zero control over the exact order in which things loaded.
Today, almost all modern Linux distributions (including Ubuntu, Debian, CentOS, and Fedora) have abandoned rc.local in favour of a powerful init system called systemd. While systemd has a slightly steeper learning curve, it provides robust features: it can restart your script automatically if it crashes, wait for the network to connect before running, and generate detailed log files if something goes wrong.
To run a script on startup in modern Linux, you must create a dedicated systemd "Service Unit" file. Here is exactly how to do it.
Step 1: Prepare Your Script
Before configuring systemd, you must ensure your script is actually executable and located in a logical directory (not sitting in your user’s Downloads folder).
- Move your script to a standard location for local binaries, such as
/usr/local/bin/.sudo cp myscript.sh /usr/local/bin/ - Make the script executable using the
chmodcommand. If the script is not executable, systemd will fail to run it.sudo chmod +x /usr/local/bin/myscript.sh
Important: Ensure your bash script has a proper "shebang" (#!/bin/bash) as the very first line of the file, otherwise systemd will not know which interpreter to use.
Step 2: Create the systemd Service File
Systemd reads instructions from simple text files ending in .service, located in a specific directory.
- Open your terminal and use a text editor (like nano) to create a new service file. You must use
sudobecause this requires root privileges.sudo nano /etc/systemd/system/myscript.service - Paste the following template into the file. This is the minimum required configuration for a basic startup script:
[Unit] Description=My Custom Startup Script After=network.target [Service] Type=simple ExecStart=/usr/local/bin/myscript.sh User=root [Install] WantedBy=multi-user.target
Understanding the Configuration:
- After=network.target: This crucial line tells systemd to wait until the server is fully connected to the internet before running your script. If your script attempts to ping an external server or download an update, it will fail if it runs too early in the boot process.
- Type=simple: This tells systemd that the script will run directly and stay in the foreground. (If your script is designed to fork into the background as a daemon, you would use
Type=forkinginstead). - ExecStart: The absolute path to your script. You must use the full path; relative paths will not work in systemd.
- User=root: Determines which user account executes the script. If your script does not require root privileges, change this to your standard username for better security.
- WantedBy=multi-user.target: This tells systemd to start this service during the normal system boot sequence (equivalent to runlevel 3 in older systems).
Press Ctrl + O to save the file, then Ctrl + X to exit nano.
Step 3: Enable and Start the Service
Just because the file exists does not mean systemd will automatically use it. You must explicitly tell systemd to reload its configuration and enable your new service.
- Tell systemd to rescan the directory for new service files:
sudo systemctl daemon-reload - Enable the service. This creates a symbolic link that tells the OS to run it on every future boot:
sudo systemctl enable myscript.service - (Optional) You do not have to reboot right now to test it. You can start the script immediately to ensure it works:
sudo systemctl start myscript.service
Step 4: Check the Status and Logs
If your script doesn’t seem to be working, systemd makes troubleshooting incredibly easy.
To check if the service is actively running or if it crashed, type:
sudo systemctl status myscript.service
If the script failed, you can view the exact error output by querying the system journal:
sudo journalctl -u myscript.service -b
By migrating your startup scripts to systemd, you ensure your Linux infrastructure is resilient, predictable, and significantly easier to debug.