Recommended Free Tools
A Linux daemon is a long-running, non-interactive process that provides a service or supervises system work. A Bash command ending in & is only a background job; it is not automatically a daemon. For a script that must run reliably, start at boot, restart after failure, and expose logs and status, keep the script in the foreground and let a service manager such as systemd supervise it.
Daemon, service, and background job: the distinction
Daemon describes the process. Service describes the function it provides or, commonly, the managed unit representing it. A service manager starts, stops, monitors, and logs services. A background job is simply work a shell launches asynchronously.
Typical daemons handle logging, networking, scheduling, device management, or application hosting. They usually run for a long time, do not expect an interactive terminal, and may start at boot, on demand, or after an event. Traditional Unix daemons detached by forking, creating a new session, closing file descriptors, changing directory, and redirecting standard streams. On a modern systemd host, those steps are normally unnecessary: a normal foreground process is easier for the manager to track. See daemon(7).
What a Bash background command actually does
./worker.sh &
echo "$!"
The ampersand asks the current shell to run an asynchronous job. $! is the process ID of the most recently launched asynchronous pipeline, and that shell can wait for it:
#1 Best Overall
./worker.sh >worker.log 2>&1 &
pid=$!
if wait "$pid"; then
echo "worker exited successfully"
else
status=$?
echo "worker failed with status $status" >&2
fi
Use jobs, fg, bg, wait, and kill to manage jobs from that shell. The PID is meaningful to the launching shell, but it does not prove that the expected program is still running: PIDs can be reused. A shell logout, terminal hangup, closed file descriptor, missing environment, or a failed command can end the job. Background execution also supplies no restart policy, boot integration, dependency ordering, or standard status interface. Bash job-control behavior is documented in bash(1).
Keeping an ad-hoc process alive after logout
nohup ./worker.sh >worker.log 2>&1 &
nohup makes a command less vulnerable to a terminal hangup. In Bash, disown removes a job from the shell’s job table or marks it not to receive a shell-generated SIGHUP:
./worker.sh >worker.log 2>&1 &
disown -h "$!"
Neither command guarantees survival against crashes, explicit signals, resource exhaustion, reboots, or policy changes. There is no boot enablement, dependency handling, automatic restart, journal unit, or reliable stop operation. Use these techniques for experiments and short-lived administrative work that you can inspect and stop manually. For the Bash builtin’s exact behavior, see the GNU Bash Reference Manual.
Choose the mechanism that matches the workload
| Mechanism | Use it when | Service supervision? |
|---|---|---|
command & |
A short task may end with the shell session. | No |
nohup or disown |
An ad-hoc command should tolerate terminal closure. | No |
tmux or screen |
You need to reconnect to an interactive development or administration session. | No |
cron or a systemd timer |
Work should run periodically and then exit. | For scheduling, not a continuous worker |
| systemd service | A process must run continuously, start on demand or at boot, restart, log, and stop cleanly. | Yes |
The modern Bash-daemon pattern: a foreground script under systemd
1. Write a service-friendly script
#!/usr/bin/env bash
set -Eeuo pipefail
cleanup() {
printf '%sn' "Stopping worker" >&2
}
trap cleanup TERM INT
while :; do
printf '%sn' "Worker heartbeat"
sleep 30
done
Save it as /usr/local/libexec/example-worker and make it executable:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
sudo chmod 0755 /usr/local/libexec/example-worker
- Keep the process in the foreground; do not add
&or double-fork boilerplate. - Use an absolute interpreter path and deliberate command paths or
PATH. - Do not assume aliases, functions, profile files, a home directory, a terminal, or standard input.
- Write normal messages to standard output/error so the manager can collect them.
- Trap
SIGTERMwhen cleanup is required and return nonzero status for failure. - Quote variables, avoid
eval, validate external input, and make repeated starts safe.
set -Eeuo pipefail can expose bugs but is not a substitute for deliberate error handling; its context-sensitive behavior should be tested with the script.
2. Create the unit
[Unit]
Description=Example Bash worker
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/libexec/example-worker
Restart=on-failure
RestartSec=5s
User=example-worker
Group=example-worker
WorkingDirectory=/var/lib/example-worker
[Install]
WantedBy=multi-user.target
Save this as /etc/systemd/system/example-worker.service. Type=simple is the normal choice when ExecStart remains in the foreground. Do not use Type=forking unless the program really daemonizes itself; add PIDFile= only when that model requires it. ExecStart is not parsed by a shell, so operators such as pipes, redirection, &&, and globbing do not work there. If shell syntax is unavoidable, invoke it explicitly, for example /usr/bin/bash -c '...', accepting the added quoting and signal complexity.
3. Install, start, and inspect it
sudo systemctl daemon-reload
sudo systemctl enable --now example-worker.service
sudo systemctl status example-worker.service
These commands control the lifecycle:
sudo systemctl start example-worker.service
sudo systemctl stop example-worker.service
sudo systemctl restart example-worker.service
sudo systemctl reload example-worker.service
sudo systemctl disable example-worker.service
sudo systemctl is-active example-worker.service
sudo systemctl is-enabled example-worker.service
reload only has an effect if the script and unit implement a reload action. Restart=on-failure restarts unexpected failures but allows a deliberate clean exit; choose another policy only when that behavior is wanted.
4. Read the journal
sudo journalctl -u example-worker.service
sudo journalctl -u example-worker.service -f
sudo journalctl -u example-worker.service -b
On systemd-based Linux, standard output and error normally go to the journal. A separate log file can be appropriate for application-specific retention, but it needs correct permissions and rotation; an unbounded file can exhaust the disk. The system and service manager is documented in systemd(1).
Free tools Windows power users keep installed
One-click scans. No signup required.
Run with least privilege
Do not run an application script as root unless it needs root-only access. An illustrative system account setup is:
Rank #4
sudo useradd
--system
--home-dir /var/lib/example-worker
--create-home
--shell /usr/sbin/nologin
example-worker
sudo install -o root -g root -m 0755
example-worker /usr/local/libexec/example-worker
sudo chown -R example-worker:example-worker /var/lib/example-worker
Account options and conventions differ by distribution. Ensure the service user can read the script and configuration, write only the state directories it needs, and access required sockets or devices.
User services versus system services
A system unit in /etc/systemd/system/ runs independently of a particular login and can be enabled for boot. A per-user unit belongs at ~/.config/systemd/user/example-worker.service:
systemctl --user daemon-reload
systemctl --user enable --now example-worker.service
systemctl --user status example-worker.service
journalctl --user -u example-worker.service
Depending on distribution configuration, a user manager can stop when the session ends. To keep it available without an active login, a user may enable lingering:
Best Value
- New
- Mint Condition
- Dispatch same day for order received before 12 noon
- Guaranteed packaging
- No quibbles returns
loginctl enable-linger "$USER"
Verify that user managers and lingering are enabled on the target host before relying on this behavior.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.When a timer or cron is better than a daemon
If a task should run every interval, perform work, and exit, use a scheduler rather than an idle loop such as while true; do do_work; sleep 60; done. A systemd timer paired with a one-shot service provides explicit scheduling, dependencies, logs, and status. cron remains suitable where it is the established scheduler; it is a scheduler ecosystem, not a supervisor for a permanent worker. Define what happens when a run is missed or overlaps, because cron can start another copy while an earlier invocation is still active. See cron(8).
Traditional daemonization and why it is usually the wrong first step
Legacy init scripts often forked twice, called setsid(), changed directory, reset the umask, closed descriptors, redirected streams, and wrote a PID file. Those techniques explain historical daemon behavior, but adding them to a Bash script launched by systemd can hide the real process from the manager or make stop and restart tracking unreliable. Keep a systemd service as one foreground process. In a container, the usual pattern is likewise one foreground process as the container’s main process rather than a daemon that forks away.
Diagnose failures systematically
| Symptom | Likely cause | Action |
|---|---|---|
status=203/EXEC |
Wrong path, missing execute bit, or invalid shebang. | Check ExecStart, permissions, and interpreter path. |
| Works in a terminal but not under systemd | Different PATH, environment, home, directory, or permissions. |
Use absolute paths and explicit unit settings; test as the service user. |
| Exits immediately | The script completed or failed during startup. | Read journalctl -u example-worker.service -b and ensure the intended foreground loop exists. |
| Restarts repeatedly | Startup error or unsuitable restart policy. | Read the journal and run the script manually as the service account. |
| No expected log file | Output is in the journal or buffering differs. | Use journalctl; configure a file only with permissions and rotation. |
Permission denied |
State, configuration, or executable ownership is wrong. | Correct ownership and directory permissions. |
| Duplicate workers | Several launch mechanisms or stale PID logic. | Use one supervisor and make startup idempotent. |
| Stop hangs | The script ignores SIGTERM or leaves children behind. |
Add signal handling and ensure child processes terminate; use SIGKILL only as a last resort. |
| Dies after logout | It was a shell job or a non-lingering user service. | Use a system service or configure user-service persistence deliberately. |
Useful inspection commands include:
ps -ef
pgrep -af example-worker
systemctl show example-worker.service
systemctl cat example-worker.service
readlink -f /proc/"$pid"/exe
tr ' ' ' ' < /proc/"$pid"/cmdline
pstree -ap "$pid"
ss -ltnp
lsof -p "$pid"
PID files, signals, and duplicate prevention
A PID file can become stale after a crash and a reused PID can identify an unrelated process. That can block a valid start or terminate the wrong program. Prefer systemd’s process tracking. If a PID file is unavoidable, place it in an appropriate runtime directory, verify the executable or service identity, remove it on clean shutdown, and handle stale files safely.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesUse systemctl stop or kill -TERM for a graceful stop. Track child processes deliberately: a script can launch descendants that outlive its parent unless the service’s process-group behavior and cleanup logic are tested on the target distribution.
Quick Recap
Operational and security checklist
- Choose one launch mechanism; do not combine cron, shell startup files, and systemd for the same worker.
- Use a dedicated unprivileged account and restrictive configuration and state permissions.
- Quote variables, reject untrusted input, and never use
evalfor convenience. - Keep logs bounded through journal policy or a rotating file.
- Define lock or overlap behavior for scheduled jobs.
- Test startup, clean stop, restart after failure, reload behavior, upgrades, and reboot recovery.
- Document required environment variables, directories, ports, and external commands explicitly.
Quick decision guide
| Requirement | Use |
|---|---|
| Short command while you remain in the shell | command & |
| Ad-hoc command that should survive terminal closure | nohup or Bash disown |
| Reconnectable interactive session | tmux or screen |
| Periodic work that exits each run | systemd timer or cron |
| Continuous worker needing boot, restart, logs, dependencies, and least privilege | systemd service |
| Host without systemd, or a container/orchestrator with its own model | Use that platform’s supervisor and keep the process model in its foreground form |
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




