1

Question

Say I have a bash script test.sh with the following content:

python test.py

How can I modify the bash script so that it also suspend the python process once it received SIGTSTP itself?

Thanks in advance!


My Attempts

I tried just SIGSTOP or SIGTSTP the parent process but they child process still keep going.

I also tried trapping the signal and pass it to the child process but now I'm having trouble resuming it. Here is my code:

#!/bin/bash

suspend_pid() {
    local pid=$1
    echo "Received SIGTSTP. Suspending child process $pid"
    kill -19 "$pid"
    echo "Suspending main process $$"
    kill -19 $$
}

continue_pid() {
    local pid=$1
    echo "Received SIGCONT. Resuming child process $pid"
    kill -18 "$pid"
    echo "Resuming main process $$"
    kill -18 $$
}

python test.py &
python_pid=$!

trap "suspend_pid $python_pid" SIGTSTP
trap "continue_pid $python_pid" SIGCONT

# Wait for the Python script to complete
wait $python_pid

echo "THE END"

It succeeded in pausing the parent and child process but failed in resuming them. I got the following output when I run kill -SIGCONT <parent_pid>

Received SIGCONT. Resuming child process 26944
Resuming main process 26942
Received SIGCONT. Resuming child process 26944
Resuming main process 26942
THE END
Received SIGCONT. Resuming child process 26944
Resuming main process 26942
Received SIGCONT. Resuming child process 26944
Resuming main process 26942

I guess in continue_pid(), kill -18 $$ also calls continue_pid()?

QZ Shao
  • 11
  • 3

2 Answers2

0

Similar to this answer from Stack Overflow, you can trap the python process as follows:

#!/bin/bash

# Set a trap for SIGTSTP
trap 'suspend_python' SIGTSTP

# Function to suspend the python process
suspend_python() {
  echo "Suspending Python process..."
  kill -TSTP $!
}

# Run the python process
python test.py
PiRho
  • 23
  • 5
  • Thanks! This works for suspending the child but how can I normally resume it? I have updated the question about this part. – QZ Shao Jun 02 '23 at 22:03
0

I achieved what I wanted by just suspend/continue the child process (using SIGUSR1 and SIGUSR2) and make the parent script wait for the termination of the child process.

I changed the script to be like this:

# Function to handle SIGTSTP signal
suspend_pid() {
    local pid=$1
    echo "Received SIGUSR1. Suspending child process $pid"
    kill -19 "$pid"
}

continue_pid() {
    local pid=$1
    echo "Received SIGUSR2. Resuming child process $pid"
    kill -18 "$pid"
}

python -u test.py > test.py.out 2>&1 &
python_pid=$!

trap "suspend_pid $python_pid" SIGUSR1
trap "continue_pid $python_pid" SIGUSR2

while true; do
    process_status=$(ps -p $python_pid -o stat=)
    if [[ -n $process_status ]]; then
        sleep 1
    else
        break
    fi
done

echo "The End"

It works pretty good.

QZ Shao
  • 11
  • 3