There is this lil program in moreutils called
ifne. I use it in shell pipelines, to execute a given command when there is some output. A quick example:
grep "^`date +%F`" logs/feedsubscription/api.log \ | grep '"message":"subscribe"' \ | ifne mail -s "Subscription requests" root
This will grep the API log, and email me today’s subscription requests, but only if there are any. It won’t do anything if there are no records found — and that’s exactly its whole purpose: only run the command if anything comes into STDIN.
Its limitation is that I can only run one command on that STDIN, and I wanted to do some more processing on it before passing it to the next command in the pipeline. Specifically this: grep some log file and email the matching lines, but first prepend some headers, which would look like this:
grep 'something' file \ | ( echo "Subject: Subscribe report" echo "From: email@example.com" echo "" cat ) \ | ssmtp firstname.lastname@example.org
This doesn’t work as I wanted because it would send the email even if no lines matched. So I thought: if I pack the pre-processing and the sending in a
send_report function, I’d be able to call that function with
ifne only when there are matching lines, something like this:
grep 'something' file | ifne send_report send_report: No such file or directory
…it seems like it doesn’t work with functions. After some googling, I found this approach:
export -f send_report grep 'something' file | ifne bash -c send_report
It’s a bit awkward, but still readable and does what it needs to do.