| 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:
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"
EOFMake it executable:
sudo chmod 755 /usr/local/sbin/boot-network-task.shRun it once by hand, then read the log to confirm the line format:
sudo /usr/local/sbin/boot-network-task.shThe script prints nothing on success, so check the log line it wrote:
sudo tail -1 /var/log/boot-network-task.logSample output:
time=2026-08-21T11:14:44+05:30 boot_id=9d4e7e19-e567-4973-a623-5b3622e30289Create the systemd service
Create /etc/systemd/system/boot-network-task.service:
[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.targetThis 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:
sudo systemctl daemon-reloaddaemon-reload normally produces no output on success.
Check the unit file statically:
systemd-analyze verify /etc/systemd/system/boot-network-task.serviceEnable the service for future boots:
sudo systemctl enable boot-network-task.serviceSample 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:
sudo systemctl start boot-network-task.serviceCheck that it finished successfully:
systemctl status boot-network-task.service --no-pagerSample 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:
sudo tail -1 /var/log/boot-network-task.logA new timestamp and boot_id confirm the unit ran during boot.
You can also read the service journal for the current boot:
journalctl -u boot-network-task.service -b --no-pagerSample 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.

