I use nohup
and bash scripts to help manage my python programs running on a local server. I have a bash script (tmp.sh
) to invoke several python programs in a row. I try to kill the bash script and the python scripts started within the bash script with kill $PID
, where PID
is the process ID of the command nohup bash tmp.sh &
, but only the bash script is terminated, and the python script keeps running. I don't want to export the process IDs of those python scripts because the bash script will run multiple python scripts within it and in that case I have to export the process ID of each python script.
I have created an example to reproduce the problem I have encountered.
Basically, I usually start my program by source run2.sh
, which first determines if the same program is currently running to avoid duplicated running, and if not, submit a new job and change the PID
to the new job in ~/.bashrc
.
run2.sh
submit_a_job()
{
nohup bash tmp.sh &
export PID=$! # get the process ID of the above submitted job
echo "job $PID submitted at $(date)"
echo "job $PID submitted at $(date)" >> output.log
echo "export PID=$!" >> ~/.bashrc
}
if [ -n "$PID" ]; then
# PID set, safe to run any job
if ps -p $PID > /dev/null; then
# the job is still running
echo "$PID is running, new job not submitted"
else
# the job has finished, delete previous PID, and submit a new job
echo "$PID is finished, new job submitted"
sed -i '/PID/d' ~/.bashrc
submit_a_job
fi
else
# PID not set, the job might still be running or have finished
echo "helloworld"
submit_a_job
fi
If you do not want to modify ~/.bashrc
, you can comment off the following lines in run2.sh
. And make sure you run run2.sh
with source
, otherwise the environment variable is not exported to the current working shell.
echo "export PID=$!" >> ~/.bashrc
sed -i '/PID/d' ~/.bashrc
tmp.sh
is the script that runs python jobs
time python3 while.py
while.py
is just a meaningless dead loop
import time
counter = 0
while True:
print(f"This is an infinite loop! Iteration: {counter}", flush=True)
counter += 1
time.sleep(1) # Sleep for 1 second between iterations
As I have exported the ID of the process that runs bash tmp.sh
as PID
, I can kill the bash script tmp.sh
with command kill $PID
. The problem is, even if tmp.sh
no longer runs, the python script that runs at the time I kill tmp.sh
keeps running in the background. I can confirm this point by command ps aux | grep python3
, which clearly indicates while.py
is running.
Which command should I use to kill the bash script tmp.sh
as well as the python program running at the same time I kill tmp.sh
?
Kill the whole process group, rather than just the shell process.
kill -INT -$PID
When you give a negative PID to kill
, it treats it as a process group ID.