Context:
Say I have:
(
#outer subshell
{
#inner command group, pipe-connected to ensure simultaneous invocation
do_first_thing
#die, somehow
} | {
#inner command group, pipe-connected to ensure simultaneous invocation
sleep 10
do_second_thing
}
)
echo "out"
I have an outer subshell (doesn't have to be one; it can be a command group, or could be removed entirely). Inside that, I have two pipe-connected command groups that get invoked simultaneously. I want both groups to start executing, and then, when the first group finishes (the second will still be sleep
ing), I want execution of the outer subshell to stop, where the #die, somehow
line is.
Question:
What should I do to ensure that when the #die, somehow
line is reached, everything in the #outer subshell
level terminates, but execution continues after it (i.e. out
gets printed)?
What I've Tried:
One solution is to use kill 0
(kill everything in the current process group) to get out of both internal command groups, but then the echo "out"
will never happen; the whole group will be killed, not just the outer subshell.
I've also tried temporarily overriding and then unset
ing the exit
function, but that just seems to push the problem to a different location. Perhaps I'm doing it wrong; I'm by no means a Bash guru.
Why?
Without getting into too much detail, the weird subshell-connected command groups are necessary because using &
to fork out processes does not work deterministically on my system (embedded *nix). As a result, the pipe-connected groups ensure that if do_first_thing
runs for too long (10 seconds, in the above example), do_second_thing
will occur. The actual use case is significantly more complex, but this is the root of the problem.
Cheers!
#!/bin/bash
(
#outer subshell
{
#inner command group, pipe-connected to ensure simultaneous invocation
first_step;
ps -ef | grep './lol.bash' | awk '{print $2}' | xargs kill;
#die, somehow
} | {
#inner command group, pipe-connected to ensure simultaneous invocation
./lol.bash;
}
)
echo "out"
and lol.bash contains your sleep and then the so called "second_step"... it's not very clean, but it turns.
an other way is to make a loop in the second part, that check if step one is done, for an amount of time, and then leave if so, or clean all things in first step and does some stuff if time is up...
nb: obviously you can launch at every step a distinct process, and then kill it when you want... (you just need to khnow the pid...)