Understanding how inputs are sent to pipes in Bash

"Input" and "command line arguments" are different things.

rm removes the files provided as arguments.

A pipe redirects the output of the left-hand command to the input of the right-hand command. It does not affect the command line arguments of the program on the right.

To do what you're trying to do, try using xargs to convert standard input to command-line arguments for executing a program. That's its job.

which gem | xargs rm, for example, will remove the gem in your PATH.


rm doesn't take input, it takes arguments. These are different. Arguments are the switches and filenames and so forth that you give to a program on the command line to affect its behavior. Input is the data that the program works on. For example, grep takes both input and arguments:

grep "foo" file.txt

There are two arguments there "foo" and file.txt. The input is the contents of file.txt, not the string file.txt itself. Since grep takes input, you can use it with pipes:

cat file.txt | grep "foo"

produces the same output, since cat is taking file.txt as an argument, and producing the contents of file.txt as output. That output is then piped in to grep, giving the same effect as having grep open the file itself, as in the first example.

If you want to use the output of one program as the argument to another, you use backticks:

rm `which gem`

or this alternative (bash-specific) syntax:

rm $(which gem)

Edit: or xargs as another answerer points out. Many ways to skin a cat with a command line.


Check out the man pages of commands you're interested in. These programs will indicate that they read from stdin (try man grep for a popular command that reads stdin).