import subprocess import atexit import os import signal # The preexec_fn=os.setsid argument in the Popen calls is used to start the bash processes in new process groups. # This allows us to kill the processes and all their child processes (if any) by sending a signal to the process group. def run_bash_commands(cmd1, cmd2): # Start the bash processes process1 = subprocess.Popen(cmd1, shell=True, preexec_fn=os.setsid) process2 = subprocess.Popen(cmd2, shell=True, preexec_fn=os.setsid) # Register a cleanup function to be called when the script exits atexit.register(cleanup, process1, process2) def cleanup(process1, process2): # Kill the bash processes os.killpg(os.getpgid(process1.pid), signal.SIGTERM) os.killpg(os.getpgid(process2.pid), signal.SIGTERM) # Example usage: run_bash_commands('sleep 10', 'sleep 20')