BASH: Pause and resume a child script

1.2k Views Asked by At

I want to control a child script somehow. I am making a master script which spawns many children scripts and need to RESUME and PAUSE them on demand.

Child

Do stuff
PAUSE
Cleanup

Parent

sleep 10
RESUME child

Is this possible?

AS PER SUGGESTIONS

Trying to do it with signals while the child runs in the background doesn't seem to work.

script1:

#!/bin/bash

"./script2" &
sleep 1
kill -2 "$!"
sleep 1

script2:

#!/bin/bash

echo "~~ENTRY"

trap 'echo you hit ctrl-c, waking up...' SIGINT
trap 'echo you hit ctrl-\, stoppng...; exit' SIGQUIT

while [ 1 ]
do
    echo "Waiting for signal.."
    sleep 60000
    echo "~~EXIT1"
done

echo "~~EXIT2"

Running:

> ./script1
2

There are 2 best solutions below

3
On BEST ANSWER

One way to control individual process scripts is with signals. If you combine SIGINT (ctrl-c) to resume with SIGQUIT (ctrl-) to kill then the child process looks like this:

#!/bin/sh
trap 'echo you hit ctrl-c, waking up...' SIGINT
trap 'echo you hit ctrl-\, stoppng...; exit' SIGQUIT

while (true)
do
    echo "do the work..."
    # pause for a very long time...
    sleep 600000
done

If you run this script, and hit ctrl-c, the work continues. If you hit ctrl-\, the script stops.

You would want to run this in the background then send kill -2 $pid to resume and kill -3 $pid to stop (or kill -9 would work) where $pid is the child process's process id.

Here is a good bash signals reference: http://www.ibm.com/developerworks/aix/library/au-usingtraps/

-- here is the parent script...

#!/bin/sh

./child.sh & 

pid=$!

echo "child running at $pid"
sleep 2
echo "interrupt the child at $pid"
kill -INT $pid # you could also use SIGCONT

sleep 2
echo "kill the child at $pid"
kill -QUIT $pid
0
On

One way is to create a named pipe per child:

mkfifo pipe0

Then redirect stdin of the child to read from the pipe:

child < pipe0

to stop the child:

read _

(the odd _ is just there for read to have a place to store the empty line it will read).

to resume the child:

echo > pipe0

A more simple approach would be to save the stdin which gets passed to the child in form a pure file descriptor but I don't know the exact syntax anymore and can't google a good example ATM.