Shell Script – How to Make a Pipeline Wait for End-of-File or Stop After an Error

pipescriptingshell-script

I tried the following command after watch this video on pipe shenanigans.

man -k . | dmenu -l 20 | awk '{print $1}' | xargs -r man -Tpdf | zathura -

It basically prints a list of manpages to dmenu for the user to select one of them, then it uses xargs to run man -Tpdf % (print to stdout a pdf of the manpage git from the xargs' input) and pass the pdf to a pdf reader (zathura).

The problem is that (as you can see in the video) the pdf reader starts even before I select one manpage in dmenu. And if I click Esc and select none, the pdf reader is still open showing no document at all.

How can I make the pdf reader (and any other command in a pipe chain) to only run when its input reach a end-of-file or when it receives an input at all? Or, alternatively, how can I make a pipe chain to stop after one of the chained commands returns a non-zero exit status (so that if dmenu returns an error for not selecting an option, the following commands are not run)?

Best Answer

How can I make the pdf reader (and any other command in a pipe chain) to only run when its input reach a end-of-file or when it receives an input at all?

There is ifne (in Debian it's in moreutils package):

ifne runs the following command if and only if the standard input is not empty.

In your case:

… | ifne zathura -
Related Question