Pipe Input – Why Certain Programs Like Readlink Can’t Take Input from a Pipe

pipe

I have a symbolic link to a script in my $PATH whose file I wanted to edit. I forgot the filepath, so I tried to do the following:

$ which my_script_link | readlink

I expected that to output the filepath, but instead it output

> readlink: missing operand
> Try 'readlink --help' for more information

I have seen similar behavior before in other situations (like trying to pipe a list of files into vim for editing). I know there are workarounds, like a subshell readlink $(which my_script_link), but I want to understand why piping doesn't work the way I think it should in this situation.

Thanks!

Best Answer

Simply put, because the program is not written to do so. It is up to the programmers to decide if their software can read from STDIN or if it requires an input file. In the case of readlink, its man page states (emphasis mine):

readlink - print resolved symbolic links or canonical file names

SYNOPSIS
readlink [OPTION]... FILE...

As a general rule, programs that take input from STDIN are designed to somehow parse that input. When you pipe data to readlink it receives a text stream and has no idea what to do with it since it only deals with files and not their contents. The same is true for programs like ls or cd or cp etc. Only programs that deal with text/data streams can accept input from a pipe.

Related Question