2

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?

Martin Vegter
  • 358
  • 75
  • 236
  • 411

2 Answers2

9

Use this format:

printf ""     | ifne sh -c  "cat - ; echo 'stream not empty' "

Output is none, and:

printf "bb\n" | ifne sh -c  "cat - ; echo 'stream not empty' "

Output is:

bb
stream not empty
agc
  • 7,223
Baba
  • 3,279
2

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.

mr.spuratic
  • 9,901
  • You're also likely to get a Write error by tee if the output is large or slow enough as echo (here a standalone echo executable), will exit immediately without reading its input, so pee will soon see a broken pipe. – Stéphane Chazelas Apr 20 '21 at 06:44