Reputation: 322
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
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
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
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