Larry
Larry

Reputation: 322

Bash: Capturing the output from a command and conditionally processing it

Is there a better way to handle the following standard-ish way of conditionally handling output?

output="$(program | grep -E 'some text')"
if [ ! -z "$output" ]; then
    echo "$output" | mail -s 'captured output' to
fi

I was thinking of something along the lines of the obviously wrong

program | grep -E 'some text' | { [[ $? == 0 ]] && mail -s 'captured output' to; }

Upvotes: 0

Views: 91

Answers (3)

Fred
Fred

Reputation: 7015

There is a way to do it without having to capture the output. In some cases (i.e. huge output), this could be preferable. Something like this, which can be reused easily :

execute_on_input()
{
  local c=
  local r=0
  IFS= read -r -n 1 c  || r=$?
  [[ "$c" ]] || return 0
  { echo -n "$c" ; [[ $r != 0 ]] || cat ; } | "$@"
}


program | grep -E 'some text' | execute_on_input mail -s 'captured output'

The function checks if it can read something, and if it cannot it exits without launching the command passed in the position arguments ("$@"). If output is found, it is piped to the command received in positional arguments (the first character read first, then, with cat, the rest of the output that was not read with the first read).

Upvotes: 2

Walter A
Walter A

Reputation: 20032

You can replace if [ ! -z "$output" ] with if [ -n "$output" ] (or if [ -n "${output}" ]). Other possibilities will do the same, so why make it more difficult to read?
The explicit use of test will show what you are doing:

test -n "${output}" && echo "output filled"

Upvotes: 0

chepner
chepner

Reputation: 532538

The exit status of grep will tell you if there was a match or not.

if output=$(program | grep -E 'some text'); then
    printf '%s' "$output" | mail -s 'captured output' to
fi

However, mail (at least the version I am looking at) has an option -E that prevents an empty message from being sent, making the check unnecessary.

program | grep -E 'some text' | mail -E -s 'captured output' to

Upvotes: 1

Related Questions