5

I have a shell script which ends with a few pipes grep ... | while read ...| sort | uniq and I want to return 1 if the output is empty, but uniq always returns 0 even if its input is empty.

So far the best solution I've found is adding grep with an empty pattern ... uniq | grep '', this works perfectly but feels more like a hack.

So my question is: Is there any better/canonical way to do this?

Some restrictions:

  • I don't want to capture my output in a variable since I would need to print it again afterwards: a=$(... | uniq); printf '%s\n' "$a"; [ -n "$a" ] which doesn't feel right either.
  • If possible I'd also prefer a standard tool (no moreutils) and something portable

Thanks!

5
  • Storing it and printing it is unavoidable, even if you use a program like tee. While some programs make it look like it does not store it and print it later, that is what you have to do to check the output of a command and then running it
    – Stan Strum
    Commented Mar 24, 2018 at 18:15
  • In these cases I tend to use wc -l and check the output but this is not better than your approach.
    – Ned64
    Commented Mar 24, 2018 at 18:17
  • yeah store and print later is indeed probably what uniq and sort are doing, but the less I do it the better Commented Mar 24, 2018 at 18:20
  • What about a function like: muniq () { uniq | grep . ;}?
    – jesse_b
    Commented Mar 24, 2018 at 18:27
  • @Jesse_b yes it's easier to read but it's still a hack Commented Mar 24, 2018 at 18:29

2 Answers 2

2

Frankly, I think | grep '' is just fine. You've already used a bunch of programs in the pipeline, so forking out another one isn't going to hurt. And you already know what grep does, so there's no debugging with regard to writing some "smart" shell snippet to do it.

The comments mentioned also | grep ., which might be another possibility. grep . doesn't match on an empty line, grep '' does, so choose depending on which one you want.

Though, using grep like that might not be immediately obvious to a casual reader, so you might want to add a comment about its purpose in any case.

1
  • Yeah I guess I'll stick with this, too bad there's nothing more obvious than grep. Commented Mar 24, 2018 at 21:29
0

I think this should do the work:

[ -n "$(command | tee /dev/tty)" ]

tee will send command's output to both stdout (where it's evaluated by the test command) and your terminal (/dev/tty), so you can see the output without capturing it in a variable.

It's a POSIX-compliant solution AFAIK.

2
  • and that only works if the output from the script is going to a tty, and not redirected somewhere else... also the comsub will eat tailing newlines, making an output that contains just empty lines seem like there was no output
    – ilkkachu
    Commented Mar 24, 2018 at 19:39
  • Thanks, it would work in my case but I feel this is too much compared to just using grep, even if that's not grep's primary purpose. Commented Mar 24, 2018 at 21:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .