A program that must survive reboot belongs under the system service manager instead of a login shell. On systemd-based Linux hosts, a custom service unit lets boot start the program before anyone logs in and gives operators normal start, stop, status, and log commands for the same workload.

A service unit under /etc/systemd/system describes the program with sections such as [Unit], [Service], and [Install]. ExecStart= names the command, Type=exec makes systemd wait until the executable is invoked, Restart=on-failure restarts the process after unexpected exits, and WantedBy=multi-user.target makes enablement attach the service to the normal multi-user boot target.

This procedure creates a system-level startup service, not a graphical desktop login item. Desktop session autostart belongs in the matching desktop environment, while a command that should run once and exit at boot normally needs Type=oneshot instead of the long-running service pattern shown here. Custom system services run as root unless the unit sets User=account-name, so use a dedicated unprivileged account when the program does not need full administrator rights.

Steps to automatically run a program on Linux startup with systemd:

  1. Create or identify the script or binary that should run during boot.
    $ sudoedit /usr/local/bin/startup-demo.sh
  2. Add the program that should stay running after startup.
    #!/bin/sh
    echo "startup-demo started"
    exec sleep infinity

    Replace the example with the real command. Use a wrapper script only when the service needs setup before the main process starts.

  3. Make the startup program executable.
    $ sudo chmod 755 /usr/local/bin/startup-demo.sh
  4. Create the custom service unit file.
    $ sudoedit /etc/systemd/system/startup-demo.service
  5. Add the systemd unit definition.
    [Unit]
    Description=Startup demo service
    
    [Service]
    Type=exec
    ExecStart=/usr/local/bin/startup-demo.sh
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target

    Add User=account-name under [Service] when the program should run as a dedicated non-root account.

  6. Validate the unit file before loading it into the service manager.
    $ sudo systemd-analyze verify /etc/systemd/system/startup-demo.service

    No output means systemd accepted the unit syntax and referenced directives.

  7. Reload systemd so it reads the new unit file.
    $ sudo systemctl daemon-reload
  8. Enable the service for future boots and start it now.
    $ sudo systemctl enable --now startup-demo.service
    Created symlink /etc/systemd/system/multi-user.target.wants/startup-demo.service -> /etc/systemd/system/startup-demo.service.

    --now starts the service immediately after enablement instead of waiting for the next reboot.

  9. Confirm that systemd saved the boot-time enablement.
    $ systemctl is-enabled startup-demo.service
    enabled
  10. Check that the service is running in the current boot.
    $ systemctl status --no-pager startup-demo.service
    * startup-demo.service - Startup demo service
         Loaded: loaded (/etc/systemd/system/startup-demo.service; enabled; preset: enabled)
         Active: active (running) since Sat 2026-06-13 10:15:42 UTC; 6s ago
       Main PID: 1842 (startup-demo.sh)
          Tasks: 2 (limit: 4567)
         Memory: 512.0K
            CPU: 8ms
         CGroup: /system.slice/startup-demo.service
                 |-1842 /bin/sh /usr/local/bin/startup-demo.sh
                 `-1843 sleep infinity
  11. Review the service log from the current boot.
    $ sudo journalctl -u startup-demo.service -b --no-pager
    Jun 13 10:15:42 host.example.net systemd[1]: Started startup-demo.service - Startup demo service.
    Jun 13 10:15:42 host.example.net startup-demo.sh[1842]: startup-demo started

    -b limits the output to messages from the current boot.