1

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
Inspired_Blue
  • 2,308
  • 3
  • 15
  • 21
Pithikos
  • 18,827
  • 15
  • 113
  • 136

2 Answers2

2

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
Darryl West
  • 465
  • 2
  • 8
  • I seem to be able and get this working if it's run in the foreground and I hit `CTRL+C`. If it's in the background and I `kill -INT pid` it just exists!? – Pithikos Aug 26 '14 at 16:26
  • I just added a parent script to demonstrate. Hope that helps. – Darryl West Aug 26 '14 at 17:43
  • As a reminder for everyone else with the same issue, I would like to point out that you should use `SIGCONT` to resume the job as that's what it's intended to. – Pithikos Aug 27 '14 at 13:13
1

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.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820