views:

386

answers:

2

hi,

I've got two commands foo and bar.

foo runs for a long time without stdin or stdout/stderr activity. bar is a client of foo and runs with stdout/stderr but no stdin activity.

I'd like to run them from one shell, being able to kill both with ctrl-c, and to see the output from bar as it occurs.

i.e. something like this sequence

foo & bar kill -9

but without having to manually do the kill - instead it just happens on ctrl-c

is there a way of scripting this?

thanks

+2  A: 

You can set up a bash script to run the programs and use trap to capture the CTRL-C. Then, in the function called by trap, just kill off the programs.

It's been a while since I did this but I think the following illustrates it.

#!/bin/bash
xx() {
    kill -9 $pid1
    kill -9 $pid2
    echo bye
}
trap 'xx' SIGINT
sleep 1000 &
pid1=$!
sleep 2000 &
pid2=$!
sleep 3600

Just run this script and CTRL-C it, you'll find that it kills off the two sleep processes.

paxdiablo
+2  A: 

Don't use kill -9.

You want to trap on EXIT, not on INT.

trap 'kill $fooPid $barPid' EXIT
foo & fooPid=$!
bar & barPid=$!
wait

This solution will always make sure to terminate foo and bar, whatever the reason for it exiting (excluding it being SIGKILL'ed).

If you want to avoid keeping PIDs (which has some race condition issues) you can do this instead:

trap 'kill $(jobs -p)' EXIT
foo &
bar &
wait

That's a better (and cleaner!) solution if your script has no other jobs.

Ps: These solutions mean foo and bar can write to your terminal (your script's stdout), but neither can read from stdin. If you need either foo or bar to read from stdin, the solution becomes a bit more complex.

lhunath
Agree with everything you say except the kill -9. I've seen that touted before but it's fine if you understand what the processes do. As long as they have no resources that outlive the process, -9 is fine, and avoids the (possibly) messy staged kills (kill ,then kill -9 later if they refuse to die).
paxdiablo
@Pax: If you know what the process does and it doesn't need any cleanup then SIGTERM is 100% identical to SIGKILL, so you might as well send SIGTERM. And messy staged kills should indeed be avoided at all costs; by sending only SIGTERM and growing patience :-)
lhunath