Bash – Using “ifne” in a pipeline – running multiple commands

bashpipeshell-script

In my script, I am using the ifne utility from the moreutils package. The line can be simplified to the following:

printf "asdf\n" | ifne cat - && echo "stream not empty"

ifne executes only if the stream is non-empty. But how can I make the second command (echo "stream not empty") also execute only if the stream is non-empty? For example, how can change the following command so that it doesn't print "stream not empty"?

printf "" | ifne cat - && echo "stream not empty"

Surrounding cat and echo with parentheses generates a syntax error:

printf "" | ifne (cat - && echo "stream not empty")

How can I execute the last command only if stream is non-empty?

Best Answer

ifne doesn't set an exit code based on whether the input is empty or not, so && and || aren't going to work as hoped. An alternate approach to Babyy's answer is to use pee from the same package:

printf "asdf\n" | pee 'ifne cat -' 'ifne echo "stream not empty"'

This works like tee, but duplicates the input stream into a number of pipes, treating each argument as a command to run. (tpipe is a similar command, but behaves slightly differently.)

A possible issue though is that each of the commands may be writing to stdout in parallel, depending on buffering and length of input/output there is a chance that output will be interleaved, or vary from run to run (effectively a race). This can probably be eliminated using sponge (same package) instead of cat, and/or other buffering/unbuffering solutions. It affects the example you gave, but may not affect your real use-case.

Related Question