Elegantly Running Background Startup Scripts in Linux
Elegantly Running Background Startup Scripts in Linux
In a Linux environment, we often need to run scripts in the background for a long time. We must use Linux terminal commands to ensure that the script continues executing even after the shell terminal is closed, while also redirecting logs to a log file. This article uses launching a local script my_script.sh as an example to introduce three common background startup methods.
1. tmux / screen (Recommended for Development and Visual Monitoring)
tmux / screen are terminal multiplexers: they create a session independent of the SSH connection. All processes started within that session are bound to its pseudo-terminal (pty). Even if the SSH connection drops, the tmux session continues running in the background, and you can later reattach to view output or interact with it.
Key Point: The process does not depend on the current SSH terminal; you can detach and reattach at any time.
Startup Command
# Create a new session and enter it
tmux new -s new_session
# Run your script inside tmux (example)
bash ./my_script.sh > run.log 2>&1
# Press Ctrl-b d to detach, leaving the task runningReconnecting
tmux ls # List sessions
tmux attach -t new_session # Reattach to the sessionTerminating the Session
# Inside the session, use Ctrl-c or kill the PID; or externally:
tmux kill-session -t new_session2. setsid – Complete Detachment from Session (Recommended for One-Time Complete Detachment)
setsid in Linux is used to create a new session and make the calling process the leader of that session. A process launched with setsid no longer belongs to the original controlling terminal, so closing the terminal does not send SIGHUP to it (barring external forces). Combined with redirecting stdin to /dev/null and redirecting stdout/stderr to a file, it ensures maximum immunity from terminal influence.
Key Point: Changes session/pgid, completely detaching the process from the original terminal's process group and session. However, you cannot reattach to view an interactive terminal like with tmux (you must check log files). It does not prevent SIGTERM/SIGKILL or external schedulers from killing the process.
Startup Command
# Recommended one-liner (creates PID file, redirects stdin)
setsid bash ./my_script.sh > run.log 2>&1 < /dev/null &
echo $! > ./my_script.pidTerminating the Process
kill $(cat ./my_script.pid)
# If unresponsive, force kill:
kill -9 $(cat ./my_script.pid)Notes
- Always include
< /dev/nullto prevent the process from blocking when needing stdin or behaving abnormally upon terminal closure. - If the script forks child processes, ensure they correctly inherit the session/pgid (usually normal).
- If the program internally sets signal handlers or restores
SIGHUP, it must be handled within the program or a wrapper script.
3. nohup + disown + stdin Redirection (Common but More Error-Prone Than setsid)
nohup makes the process ignore the SIGHUP signal (sets signal disposition to IGN) and, if necessary, redirects stdout to nohup.out. disown (a shell built-in) removes a background job from the shell's job table, preventing the shell from sending additional signals to the job upon exit. Combined with & (background execution) and stdin redirection, it can achieve session detachment.
Key Point: nohup prevents SIGHUP; disown prevents shell job management upon termination; < /dev/null avoids stdin issues. The commands are simple and highly compatible (supported by almost all Unix shells). Suitable for quick backgrounding of tasks.
Drawbacks
- Poor support for complex pipelines (
nohup cmd | teeonly applies to the leftcmd; other commands in the pipe may be terminated). - Still does not protect against
SIGTERM/SIGKILLand cannot guarantee child process behavior (more fragile thansetsid). - Care must be taken to redirect stdin and use
disown, otherwise it may fail.
Startup Command
nohup bash ./my_script.sh > run.log 2>&1 &
echo $! > my_script.pidNotes
- After using
&, record the PID withecho $!(as shown above). - If the script uses pipes (
|), ensure all commands in the pipe can run correctly without a terminal, or avoid pipelines. nohupwrites output tonohup.out(if no explicit redirection is provided); it is recommended to explicitly redirect to your log file.