4

I am using solutions from Test if a command outputs an empty string. In addition to those solutions, I want to print command's output if its not empty.

I was wondering would it be possible to print command's output if its not empty by calling the command only one time.

I can do it by re-calling the same command inside the if condition, but now second call may consume additional CPU usage, since we already obtained its result.


Possible approach could be, where the same command is called two times:

if [[ $(ls -A) ]]; then
    ls -A
else
    echo "no files found"
fi

output=$(git diff --ignore-blank-lines --color-words HEAD | tr -d ' \n\r\t ' | wc -c)
if [ "$output" -gt 0 ]; then
    git diff --ignore-blank-lines --color-words HEAD 
else
    echo "diff is empty"
fi
13
  • 3
    Note that for the specific case of checking the number of names in a directory, ls is not the best tool for the job. It would be better to set -- * (possibly setting nullglob and/or dotglob in bash first) and then look at "$#".
    – Kusalananda
    Jul 5, 2021 at 14:56
  • 1
    Note that this question would have had a totally different set of answers, had you mentioned that you used the zsh shell.
    – Kusalananda
    Jul 5, 2021 at 18:24
  • 1
    @alper, you're using Zsh, but your question is tagged with bash in particular and not zsh?
    – ilkkachu
    Jul 5, 2021 at 19:43
  • 1
    Technically, the answer to the question in the title, to "check if output is non-empty, and print it if it is", is to just print it unconditionally. Since printing an empty output doesn't do anything. But that's not exactly what you want.
    – ilkkachu
    Jul 5, 2021 at 19:45
  • 1
    @alper as two answers there say, it's from the moreutils package. You'll need to install that package.
    – muru
    Jul 7, 2021 at 9:54

3 Answers 3

8

Note: The question was originally tagged , but OP has since stated that the shell used is zsh. This will invalidate the answer somewhat.

You can store the output of a command in a variable and test if that variable is empty:

output="$(your_command)"

if [[ -n $output ]]
then
    printf -- "%s\n" "$output"
else
    printf -- "No output\n"
fi

The -n test will check if $output is a non-empty string. If it is, the content of $output will be printed. Otherwise, a message that no output was produced will be printed. Notice that the quotes around the "$output" are necessary.

Notice also that (as mentioned by @ilkkachu), trailing newlines will be removed by the command substitution, so if you care about these, a different approach is necessary.

0
3

If you want the output in any case, you can pipe it to tee and use that to duplicate the output without running the command again: once to standard output, once to a command which can act on empty input.

For example:

ls | tee >([ $(wc -m) -gt 0 ] || echo No output)

Note that this only takes care of standard output, so you can end up with “No output” after an error message. You’ll also have to adjust commands accordingly when their output varies depending on whether it’s going to a terminal or not (e.g. ls -C, or output with colours).

4
  • If the folder is empty it prints ls's output and No output right after it. Is it normal?
    – alper
    Jul 5, 2021 at 19:01
  • 1
    What output do you get from ls when the folder is empty? It shouldn’t output anything, and then the above adds “No output” as a result... Jul 5, 2021 at 20:52
  • Got it. I was trying ls | tee >([ $(wc -m) -gt 100 ] || echo some_output) on non-empty folder hoping to get on some_output output. But as I understand, if the folder is not empty, it will always print the ls output
    – alper
    Jul 5, 2021 at 22:44
  • Yes, this is an answer to your stated question, “Test if a command's output is an empty string”. Solving your other question about piping output to less if it’s too long is a different matter. Jul 6, 2021 at 8:39
1

Taking ls -A as command example, the following will do:

if ls -A | grep ^; then
   : the output was already written
else
   : no output
fi

if ! ls -A | grep ^; then
   : handle the no-output condition
fi

This will also ensure that trailing newlines are preserved in the output.

For the actual case mentioned in this comment (do not run less with an empty output), there's the -F ("quit if one screen") option:

command ... | less -FXR

(you can omit the X with newer versions of less).

0

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