System Administration & Network Administration
unix shell regex grep
Updated Thu, 25 Aug 2022 10:13:18 GMT

How to signal the presence of a pattern via exit code, without altering STDOUT


I need to run cmd1. If and only if PATTERN is missing from its STDOUT, i need to run cmd2 too:

cmd1 | grep "$PATTERN"  ||  cmd2

But I'd like to see all output from cmd1, not just the lines that match PATTERN.

I know I could do something like this:

OUTPUT=`cmd1`
echo "$OUTPUT"
echo "$OUTPUT" | grep -q "$PATTERN"  ||  cmd2

but this would separate STDOUT from STDERR. Also I'd rather have a handy one-liner. So I am looking for an option in grep, or an alternative to grep, saying "Don't filter, just set the exit code".




Solution

How'bout using tee to send the output to the tty like so:

cmd1 | tee /dev/tty | grep "$PATTERN"  ||  cmd2

Example with PATTERN matching cmd1's output:

% echo "cmd1 output" | tee /dev/tty | grep -q "output" || echo "nothing matches PATTERN"
cmd1 output

Example with PATTERN not matching cmd1's output:

% echo "cmd1 output" | tee /dev/tty | grep -q "outputttt" || echo "nothing matches PATTERN"
cmd1 output
nothing matches PATTERN




Comments (2)

  • +0 – This is exactly what I was thinking - tee allows a 'fork' of stdout so that it can be acted upon and also displayed unmolested. — Mar 23, 2017 at 16:30  
  • +0 – Nicely universal, thx. — Mar 25, 2017 at 23:39