abort spawned program when it prints a specific warning

2

My Bash 4 script calls a third-party program P (one that I can't recompile), which prints warnings to STDOUT. When it prints yikes, it also enters an infinite loop. So when I detect a yikes, how can I immediately stop P and return control to my script? (And let P finish normally otherwise.)

Possibly useful fragments:

(echo $BASHPID > /tmp/subpid; ./P | tee /tmp/Pout ) &

tail -f /tmp/Pout | grep -m1 yikes && kill -9 $(cat /tmp/subpid)

wait

Camille Goudeseune

Posted 2017-10-19T16:33:19.767

Reputation: 1 361

Answers

1

Use expect:

P | { expect -c 'expect -timeout -1 yikes' && killall P ; }

This usage may not be optimal, still expect is the right tool for the job.

If P prints more after yikes then it will notice the broken pipe, so the killall isn't needed:

P | expect -c 'expect -timeout -1 yikes'

Kamil Maciorowski

Posted 2017-10-19T16:33:19.767

Reputation: 38 429

Recent Ubuntus don't include it by default. sudo apt-get install expect? – Camille Goudeseune – 2017-10-19T17:43:50.620

In my case, after yikes, P prints an infinite number of lines! – Camille Goudeseune – 2017-10-19T17:45:27.153

1

coproc ./P
grep -q -m1 yikes <&${COPROC[0]} && [[ $COPROC_PID ]] && kill -9 $COPROC_PID

Demo:

coproc { sleep 1; echo yikes; sleep 2; }; grep -q -m1 yikes <&${COPROC[0]} && [[ $COPROC_PID ]] && kill -9 $COPROC_PID
coproc { sleep 1; echo zzzzz; sleep 2; }; grep -q -m1 yikes <&${COPROC[0]} && [[ $COPROC_PID ]] && kill -9 $COPROC_PID

Found from https://stackoverflow.com/a/26779617/2097284.

However, https://unix.stackexchange.com/questions/86270/how-do-you-use-the-command-coproc-in-bash explains why named pipes are better (although deadlock isn't possible here), and why expect is better yet.

Camille Goudeseune

Posted 2017-10-19T16:33:19.767

Reputation: 1 361