How to Make Bash Scripts Self‑Terminate Cleanly with Traps and Kill
This article explains why background loops in Bash scripts survive script termination, shows how they become orphaned under init/systemd, and provides robust techniques—including kill, killall, pkill, and trap handlers—to ensure all child processes are terminated when the script exits.
1. Script Self‑Termination
When a Bash script launches background tasks (for example sleep 50 &) and then reaches the end of its flow, those background processes are re‑parented to init / systemd and continue running after the script exits.
# cat test1.sh
#!/bin/bash
echo $BASHPID
sleep 50 &After the script finishes, the sleep process’s parent PID becomes 1. Killing the script’s main PID does not stop the background sleep because a second shell process created for the while loop remains.
# cat test1.sh (with kill)
#!/bin/bash
echo $BASHPID
while true; do
sleep 50
echo 1
done &
kill $!If the background loop is placed inside while, for or until, simply killing $BASHPID is insufficient; an additional shell process that provides the loop’s execution environment stays alive and its children are inherited by init.
To analyze the situation, a second script test2.sh can be created:
#!/bin/bash
echo $BASHPID
while true; do
sleep 50
echo 1
done &
sleep 60Running pstree -p | grep test2.sh reveals two test2.sh processes: one is the script itself, the other is a subshell that hosts the background while. When the main script is killed, the subshell is re‑parented to init and continues looping.
One simple way to achieve “script suicide” is to kill all processes that share the script’s name before the script exits:
# cat test1.sh (basic killall)
#!/bin/bash
echo $BASHPID
while true; do
sleep 50
echo 1
done &
killall `basename $0`However, this approach fails when the script is invoked as bash test1.sh because the process name becomes bash. A more robust solution uses pkill -f together with the background job’s PID ( $!).
# cat test1.sh (robust version)
#!/bin/bash
trap "pkill -f $(basename $0)" SIGINT
echo $BASHPID
while true; do
sleep 50
echo 1
done &
pid=$!
kill $pid
pkill -f $(basename $0)A fully generic version places all cleanup commands in a trap that handles SIGINT, SIGTERM, EXIT and ERR:
#!/bin/bash
trap "pkill -f $(basename $0); exit 1" SIGINT SIGTERM EXIT ERR
while true; do
sleep 1
echo \"hello world!\"
done &
# other foreground work …
sleep 60Another concise method uses the special PID 0 with kill. Sending a signal to PID 0 delivers it to every process in the current process group, effectively terminating the script and all its children:
#!/bin/bash
trap "echo 'signal_handled:'; kill 0" SIGINT SIGTERM
while true; do
sleep 5
echo \"hello world! hello world!\"
done &
sleep 602. Special Nature of Bash Built‑ins
Built‑in commands such as while, for, until, if and case rely on a Bash process to provide an execution environment. When they are run in the background, Bash spawns a new subshell (a new Bash process) to host them.
If the background command is started from an interactive shell, the parent is a newly created Bash process.
If it is started from a script, the script’s own Bash process acts as the parent.
When the parent Bash process is killed, the subshell (and any processes it created) become children of init / systemd. Non‑built‑in commands do not have this dependency and can be terminated directly.
Examples such as if true; then sleep 10; fi & or while true; do sleep 2; done & demonstrate that a new Bash process appears (visible with pstree) before the actual background command runs.
Understanding this behavior is essential for reliable script cleanup, especially when scripts contain long‑running background loops that must be stopped when the script receives Ctrl+C or other termination signals.
For further reading, see the original article at https://www.cnblogs.com/f-ck-need-u/p/8661501.html (copyright belongs to the original author).
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Linux Cloud Computing Practice
Welcome to Linux Cloud Computing Practice. We offer high-quality articles on Linux, cloud computing, DevOps, networking and related topics. Dive in and start your Linux cloud computing journey!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
