What commands would I use to create two child processes serially?

Solution 1:

You can use the xargs utility for this. It can run a command for each line on stdin, so we just need to ensure that xargs gets as input a single line on stdin at the time it should start the command, which can be accomplished with grep:

proc1 | grep --max-count=1 "${targetString}" | xargs --max-lines=1 --no-run-if-empty --replace -- proc2

The arguments --max-count=1, --max-lines=1 and --no-run-if-empty ensure that proc2 is started exactly once if and when proc1 outputs ${targetString} for the first time, and never if proc1 never outputs ${targetString}. The --replace avoids that xargs appends the input line to its command line.

I used the following command line to test it:

(echo Start >&2; sleep 3 ; echo Trigger; sleep 3; echo End >&2) | grep --max-count=1 Trigger | xargs --max-lines=1 --no-run-if-empty --replace -- echo "Triggered"

Solution 2:

I'm not sure there is an elegant command / answer to the question you asked (i.e. reach a certain point in its execution) - but there are tools / techniques which can be used to bodge up a solution, probably involving more than 1 of the following, and maybe other things I don't know about yet:

  1. Backgrounding processes (&)
  2. Conditional execution (&& and ||)
  3. sleep
  4. wait (I expect this will be particularly useful - if you launch more than 1 job in the background, it will wait until all the jobs are completed)
  5. Named pipes (which could provide a mechanism to talk between processes).
  6. inodenotifywait

Writing and checking lock files is also common practice (pro tip - if you have control of the environment, write to the ramdisk rather than /tmp - on many distros this is /dev/shm).

Solution 3:

This is just an idea, but have the first process pipe its output to grep. Have grep pipe its output to a read line loop, and compare each line with what you're looking for. Once found, execute proc2.

#!/bin/bash
targetString="line you are looking for"
proc1 | grep "${targetString}" |
while read line
do
if [ "$line" = "${targetString}" ]; then
    proc2
fi
done

If "a certain point in its execution" can be determined by stdout, then how about the following?

proc1 | grep "stdout trigger string" && proc2

&& should fire when grep returns 0, which it only does when it finds a match.