I'm working with a program that outputs error messages when something goes wrong, but does not set its exit status accordingly: the exit status is always 0, indicating success. I'd like to run this program from a shell script and get a non-zero exit status if it emits any error messages, so the script can tell that the program failed.
The error messages follow a predictable pattern that I can match with
grep sets its exit status based on whether it found a match, so I can pipe the program's output into
grep and negate the result with
! to get the exit status I want.
The problem is that if I pipe into
grep, I can't see the program's output anymore, because
grep consumes it. I'd like to somehow scan the output for error messages but also display the output normally, since there are other important messages besides the errors. Unfortunately,
grep doesn't have an option to pass-through all of its input, matching and non-matching lines alike.
One approach I've found that mostly works is:
! my_program | tee /dev/stderr | grep -q "error message"
This feeds the program's output into
grep but also copies it to standard error, which isn't redirected, so I can see it. That's OK when my script's standard output and standard error both go to a terminal (so it doesn't matter which one gets the messages), but it can cause problems if standard out and standard error are redirected to different places; the messages will end up in the wrong place.
bash or POSIX shell, and GNU tools, is there a (concise) way to scan a program's standard out and/or standard error streams with something like
grep and set exit status accordingly, but also let both streams go to their normal destinations?
my_program writes its error messages to standard out, not standard error, so a solution that can only scan the standard output stream is OK, though not ideal. And in case it makes a difference, I'm doing this on CentOS 7.)