Run a Script at Linux Boot with systemd (Without cron)

Deepak Prasad
Tested on RHEL 10.2 (Coughlan) — vm1.lab.example
Package systemd 257-23.el10_2.2
Applies to Ubuntu, Debian, Kali Linux, Linux Mint, Pop!_OS, Raspberry Pi OS, elementary OS, Zorin OS, Parrot OS, MX Linux, RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora, Arch Linux
Privilege sudo or root
Scope Create a oneshot systemd service that runs a script once per boot after network-online.target, reload units, enable at boot, and verify with journalctl. Does not cover delayed timers, shutdown hooks, or cron migration.
Related guides Run script before login prompt
Run script after N minutes of boot
Create a systemd service
systemd timers
systemctl command

Use a systemd service unit when you need a script to run once each boot after the host's network configuration is ready. Cron can run jobs with @reboot, but systemd is usually a better fit when you need explicit boot ordering, systemctl status, and journal logging.

This guide places a short script in /usr/local/sbin, wires it to network-online.target, and enables it so it runs again on every reboot. Put custom units under /etc/systemd/system/; distribution units are commonly under /usr/lib/systemd/system/ (and /lib/systemd/system/ on some systems).


Create the script

Store the custom boot script in /usr/local/sbin:

bash
sudo tee /usr/local/sbin/boot-network-task.sh <<'EOF'
#!/bin/bash
LOG=/var/log/boot-network-task.log
echo "time=$(date -Is) boot_id=$(cat /proc/sys/kernel/random/boot_id)" >> "$LOG"
EOF

Make it executable:

bash
sudo chmod 755 /usr/local/sbin/boot-network-task.sh

Run it once by hand, then read the log to confirm the line format:

bash
sudo /usr/local/sbin/boot-network-task.sh

The script prints nothing on success, so check the log line it wrote:

bash
sudo tail -1 /var/log/boot-network-task.log

Sample output:

output
time=2026-08-21T11:14:44+05:30 boot_id=9d4e7e19-e567-4973-a623-5b3622e30289

Create the systemd service

Create /etc/systemd/system/boot-network-task.service:

ini
[Unit]
Description=Run boot network task once after network is online
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/boot-network-task.sh

[Install]
WantedBy=multi-user.target

This unit does three things: it waits for systemd's network-ready point, runs the script once, and connects the service to the normal boot target so it starts again after every reboot.

[Unit]After=network-online.target delays the script until the network-online synchronization point. Wants=network-online.target pulls that target into the boot transaction; it uses the network manager's wait-online integration when available and configured. The target does not guarantee a particular remote server is reachable.

[Service]Type=oneshot runs the script once and exits. ExecStart= points to your script.

[Install]WantedBy=multi-user.target is what systemctl enable uses to start the unit on normal multi-user boot.


Reload and enable the service

Reload systemd so it reads the new file:

bash
sudo systemctl daemon-reload

daemon-reload normally produces no output on success.

Check the unit file statically:

bash
systemd-analyze verify /etc/systemd/system/boot-network-task.service

Enable the service for future boots:

bash
sudo systemctl enable boot-network-task.service

Sample output:

output
Created symlink '/etc/systemd/system/multi-user.target.wants/boot-network-task.service' → '/etc/systemd/system/boot-network-task.service'.

That symlink is what makes systemd start the unit on boot.


Test without rebooting

Start the unit on the running system:

bash
sudo systemctl start boot-network-task.service

Check that it finished successfully:

bash
systemctl status boot-network-task.service --no-pager

Sample output:

output
● boot-network-task.service - Run boot network task once after network is online
     Loaded: loaded (/etc/systemd/system/boot-network-task.service; enabled; preset: disabled)
     Active: inactive (dead) since Fri 2026-08-21 11:14:44 IST; 2s ago
    Process: 1284 ExecStart=/usr/local/sbin/boot-network-task.sh (code=exited, status=0/SUCCESS)
   Main PID: 1284 (code=exited, status=0/SUCCESS)

status=0/SUCCESS means the script ran. The log file is the clearest proof the task completed.


Verify after reboot

Reboot the host, then read the script log:

bash
sudo tail -1 /var/log/boot-network-task.log

A new timestamp and boot_id confirm the unit ran during boot.

You can also read the service journal for the current boot:

bash
journalctl -u boot-network-task.service -b --no-pager

Sample output:

output
Aug 21 11:14:44 vm1.lab.example systemd[1]: Starting boot-network-task.service - Run boot network task once after network is online...
Aug 21 11:14:44 vm1.lab.example systemd[1]: Finished boot-network-task.service - Run boot network task once after network is online.

Troubleshooting

Symptom Likely cause Fix
203/EXEC in systemctl status Bad path, missing +x, or script on a noexec path such as /tmp Move script to /usr/local/sbin, chmod 755, fix shebang
Unit never runs at boot Not enabled or wrong WantedBy= systemctl enable boot-network-task.service and confirm symlink
Script runs too early for NFS/API Used network.target only Switch to network-online.target with Wants=
Unit marked failed after long script Default start timeout Set an appropriate TimeoutStartSec= for a legitimately long boot task
Remote call still fails after boot Target reached but server down Retry or fail gracefully in the script

References

Summary

You run a script at boot by placing it in /usr/local/sbin and enabling a oneshot .service unit on multi-user.target that starts after network-online.target. After= and Wants= handle ordering and the network-ready synchronization point; WantedBy= is what makes the job repeat on every reboot.

Test with systemctl start before you reboot, then confirm with the log file and journalctl -u. For other timings — before login, minutes after boot, or at shutdown — see the linked guides.


Frequently Asked Questions

1. Do I need cron to run a script at boot on a systemd Linux host?

No. An enabled systemd service unit tied to multi-user.target is the usual approach. Cron can run jobs with @reboot, but systemd is usually a better fit when the script needs explicit boot ordering, dependencies, service status, and journal logging.

2. Should I use network.target or network-online.target?

network-online.target is the systemd synchronization point for services that need networking configured during boot. Its exact readiness condition depends on the network manager and its wait-online service; it does not guarantee that a particular remote server is reachable.

3. Why does my boot script fail with status 203/EXEC?

systemd could not execute the script path. Check the shebang, chmod +x, SELinux context, and avoid /tmp when noexec or restrictive policies block execution. /usr/local/sbin is a reliable location for custom scripts.

4. How is this different from running a script before the login prompt?

Boot-order timing is controlled with After= and Before= in the unit file. This guide runs after network-online.target. A separate unit ordered before getty-pre.target runs closer to the console login prompt.
Omer Cakmak

Linux Administrator

Highly skilled at managing Debian, Ubuntu, CentOS, Oracle Linux, and Red Hat servers. Proficient in bash scripting, Ansible, and AWX central server management, he handles server operations on OpenStack, KVM, Proxmox, and VMware.

  • Debian
  • Ubuntu
  • Linux
  • Red Hat Enterprise Linux
  • Shell Script
  • System Administration