My understanding is that pipe in e.g.,

command1 | command2 

sends the output of the command1 to command2. However, I would have expected this to work:

echo "tmp.pdf" | evince 

But it does not. Where is the output of echo "tmp.pdf" being sent?

3 Answers 3


Your understanding is correct. The sequence command1 | command2 is sending the output (STDOUT) of command1 to the input (STDIN) of command2. The reason your evince command didn't work is that evince doesn't accept a filename on STDIN.


A pipe sends its output to the program that has it open for reading. In a shell pipeline, that's the program on the right-hand side of the pipe symbol, i.e. evince in your example.

You're sending the file name tmp.pdf to evince on its standard input. However evince doesn't care about its standard input. Like every program that acts on a file, it expects the file name to be passed as a command line argument; if you don't pass a file name on the command line, it offers to open a file. Command line arguments are not the same thing as standard input. Humans have different input organs that input different things (e.g. you can't eat through your nose), and similarly programs have different ways of receiving information that serve different purposes.

Evince can read a file (not a file name) on standard input: evince /dev/stdin <"tmp.pdf". (This may not work on all Unix variants.) The file name /dev/stdin means “whatever file you already have open on your standard input”. Programs intended for command line typically read their standard input when they aren't given a file name, but GUI programs usually don't. Evince can only open a regular file this way, not data from a pipe (e.g. cat tmp.pdf | evince /dev/stdin doesn't work), because it needs to be able to seek back and forth in the file when navigating between pages.


You can by pass this problem as follows as I lately realized on my own. First use locate command to find the path of the file that you wish to open in evince.Then Pass this result as argument in evince.Lets say your file name is abc_xyz.pdf and you wish to open it. Then you can do- evince "$(sudo locate xyz | grep abc)". Kindly note that in case the name of your pdf file contains spaces then you need to double quote the $(sudo locate xyz | grep abc) The reason why I am using another code (piped with sudo locate xyz) i.e grep abc is to further filter down the result. But here is a catch and that is,you need to constantly update the locate by issuing sudo updatedb. Lets say you changed the location of your pdf to some new directory then locate wont be able to find itz new location as itz data base hasnt been updated. But you can use "find" command with "and" condition to get your job done as it searches in real time. For instance you can do-

evince "$(find ~/ -iname "*abc*" -a -iname "*xyz*" -type f)"

and pass this as an argument to evince.here argument -iname is for case insensitive search and -a is and condition. -type f will only return files.

You must log in to answer this question.

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