One of the things I like most about Linux is that there is always some way to automate tasks. It doesn't matter if we are talking about mounting disks, running checks, generating logs, or configuring the network: almost everything can be set up to happen automatically upon system boot.
On more than one occasion, I have needed certain commands or scripts to run automatically and transparently, without having to remember to launch them manually after every reboot. And although everything revolves around systemd nowadays, there are still several valid ways to execute commands when starting Linux.
In this guide, I explain what methods exist, when to use each one, and what errors to avoid, based on both documentation and real-world use.
One of my favorite things about Linux is that there is always some function, configuration, or program that allows for automating tasks or processes—for example, when you need to execute scripts or any other command (mounting units automatically, running a check, log, etc.) when starting our Linux distribution automatically and transparently.
Automating tasks at Linux boot: why and when to do it
Automating the startup is not just about convenience: in many cases, it is necessary.
System boot vs. User login
First of all, it is worth clarifying something that causes a lot of confusion:
- System boot: occurs when Linux starts, even before any user logs in.
- User login: occurs when a user enters the system (terminal, graphical environment, SSH, etc.).
Running a script at system boot is not the same as running it at login. In my case, for example, I needed certain scripts to run even if no one logged in, such as mounting units or applying network rules.
Real cases where automation makes sense
Some very common scenarios:
- Automatically mounting disks or volumes
- Running integrity or status checks
- Applying firewall or NAT rules
- Launching daemons or auxiliary services
- Generating logs from startup
If you have ever had to repeat the same command after every reboot, it should probably be executed automatically.
The rc.local file: the classic method that is still useful
There are many ways to execute terminal commands when logging into our Linux; one of them is through the rc.local file, which is located at: /etc/rc.local.
By default, Fedora does not include this file; however, it can be created and will be picked up by the OS without any issues.
What is /etc/rc.local and how it works
In traditional System V-based systems, the /etc/rc.local file was a script that was executed at the end of the boot process. Commands that needed to be executed automatically were placed there.
The file is plain text and can be opened by programs for that purpose such as Nano, Vim, or Gedit; when opening the file, we will see the following content:
#!/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 0If we wanted to run a sh script called script.sh at the moment Linux starts, we add:
#!/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.
sh <ruta>/script.sh
exit 0Where <path> is the path to our file.
And that's it; upon starting our system, the previously specified file will be executed.
Compatibility with systemd (rc-local.service)
Although systemd does not have a direct equivalent, it maintains compatibility through rc-local.service.
When you start a system with systemd, it checks that:
- /etc/rc.local exists
- It is executable
If both conditions are met, systemd automatically generates the rc-local.service unit and executes the script upon reaching network.target.
I have used this, for example, in Fedora (where the file does not exist by default) by manually creating /etc/rc.local without any problems.
Practical example: running a script when starting Linux
Suppose we want to run a script script.sh at boot:
#!/bin/sh -e sh /path/script.sh exit 0Don't forget to make it executable:
chmod +x /etc/rc.localThis method is ideal for simple, fast scripts without complex dependencies.
Real advantages and limitations of rc.local today
Advantages
- Simple and fast
- Ideal for specific tasks
- Runs as root
Limitations
- It is a compatibility method, not recommended for services
- Little control over the execution order
- Difficult to debug
Executing scripts at startup using cron (@reboot)
Another very useful option is to use cron with the @reboot directive.
How the @reboot directive works
Cron allows executing commands automatically when the cron daemon starts, using:
@reboot /path/script.shThis is configured by editing the crontab:
crontab -eRunning commands as user vs. as root
Commands in cron are executed with a minimal environment.
- If you use crontab -e, they run as your user
- If you use sudo crontab -e, they run as root
For critical system scripts, it is normal to use the root crontab.
When to use cron and when to avoid it
Use it if:
- The script is simple
- It does not depend on the boot order
- It does not need specific active services
Avoid it if:
- You need to control dependencies
- The script must run after another service
- You want advanced service management
Executing commands when starting Linux with systemd (recommended method)
If we are talking about modern distributions, systemd is the best option.
Why systemd is the best option today
systemd allows:
- Controlling the execution order
- Defining dependencies
- Restarting services automatically
- Viewing logs with journalctl
When I need something robust and maintainable, I always end up using systemd.
Creating a systemd service step by step
First, create your script:
#!/bin/bash pgrep dunst || setsid -f dunstMake it executable:
chmod +x /root/startup.shThen create the service:
sudo nano /etc/systemd/system/startup.serviceContent:
[Unit]
Description=Startup Script
[Service]
ExecStart=/root/startup.sh
[Install]
WantedBy=multi-user.targetActivate it:
systemctl enable startup.service --nowBoot order and dependency control
Here is the big advantage: you can use After=, Requires=, or network.target to ensure everything happens at the right time.
Advantages over rc.local and cron
- More control
- Better debugging
- Officially recommended
- Scales better
Common problems when running scripts at Linux startup
The script does not run
- Lack of permissions
- Incorrect path
- Non-existent environment variables
Interactive environment vs. startup
The environment at boot is not the same as an interactive terminal. Avoid relative paths and define everything explicitly.
Silent errors and how to debug them
- Use logs
- Redirect output to files
- With systemd, check journalctl -u service
Which method to choose to run scripts at Linux startup
Comparison:
- Method Simplicity Control Recommended
- rc.local High Low Simple cases
- cron Medium Low Specific scripts
- systemd Medium High Production
Practical recommendations
- Simple script → rc.local
- User task → cron @reboot
- Serious service → systemd
Frequently asked questions about startup scripts in Linux
- Does rc.local still work?
- Yes, thanks to systemd, but only as compatibility.
- What is the best way today?
- systemd, unless the case is trivial.
- Can I run commands as root?
- Yes, using rc.local, root cron, or systemd services.
- And when logging in?
- For that, there are .bash_profile, .bashrc, or graphical session scripts.
Conclusion
Running commands or scripts when starting Linux remains a common and perfectly valid task. Although systemd is the standard today, methods like rc.local or cron still have their place if you know when to use them.
In my experience, the key is not the method, but choosing the right one based on the context. With that in mind, you will avoid errors, save time, and have much cleaner and more automated systems.
I agree to receive announcements of interest about this Blog.
This post explains a way to execute a terminal command when starting a session is through the rc.local file that is located in /etc/rc.local