3

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!

  • 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 Mar 24 '18 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 Mar 24 '18 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 – Quentin L'Hours Mar 24 '18 at 18:20
  • What about a function like: muniq () { uniq | grep . ;}? – Jesse_b Mar 24 '18 at 18:27
  • @Jesse_b yes it's easier to read but it's still a hack – Quentin L'Hours Mar 24 '18 at 18:29
1

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.

  • Yeah I guess I'll stick with this, too bad there's nothing more obvious than grep. – Quentin L'Hours Mar 24 '18 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.

  • 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 Mar 24 '18 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. – Quentin L'Hours Mar 24 '18 at 21:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.