theonlygusti theonlygusti - 28 days ago 22
Bash Question

Scan output of process and terminate if string found

In bash, how do I start and "monitor" the output of a process for a given string?

Upon discovery of this string, I want to terminate the process.

E.g.

monitor myProgram ">>45Error;"


would launch
myProgram
and stop it as soon as it outputs
">>45Error;"

Answer

Unless myprogram handles/ignores the broken pipe signal (SIGPIPE), the following will do the job:

myprogram|grep --max-count 1 ">>45Error;"

EDIT

Here is the requested monitor script, built on top of chepner's answer and comments therein.

#!/usr/bin/env bash

set -m

tmpdir="$(mktemp -d)"
fifo="$tmpdir/fifo"
trap "rm -rf $tmpdir" EXIT

terminating_pattern=$1
shift

mkfifo "$fifo"

eval "$@" 2>&1|tee "$fifo" &

grep -q "$terminating_pattern" < "$fifo"
kill %%

Note that the input command line is executed using eval, which means that an additional level of expansions is performed. If that is undesirable, just remove the eval.

Testing:

$ ./monitor 49 'for i in {1..100}; do echo $((i*i)); sleep 1; done;'
1
4
9
16
25
36
49
./monitor: line 1:  9638 Terminated              eval "$@" 2>&1
      9639                       | tee "$fifo"