There is a distinction between command line arguments and standard input. A pipe will connect standard output of one process to standard input of another. So
ls | echo
Connects standard output of ls to standard input of echo. Fine right? Well, echo ignores standard input and will dump its command line arguments - which are none in this case to - its own stdout. The output: nothing at all.
There are a few solutions in this case. One is to use a command that reads stdin and dumps to stdout, such as cat.
ls | cat
Will 'work', depending on what your definition of work is.
But what about the general case. What you really want is to convert stdout of one command to command line args of another. As others have said, xargs
is the canonical helper tool in this case, reading its command line args for a command from its stdin, and constructing commands to run.
ls | xargs echo
You could also convert this some, using the substitution command $()
echo $(ls)
Would also do what you want.
Both of these tools are pretty core to shell scripting, you should learn both.
For completeness, as you indicate in the question, the other base way to convert stdin to command line args is the shell's builtin read
command. It converts "words" (words as defined by the IFS
variable) to a temp variable, which you can use in any command runs.
Best Answer
It sounds like the
tee
command will do what you want.The key is to use
for process substitution. With
tee
, use the following pattern:So if you wanted to use the output of
ls
as input to two differentgrep
programs, save the output of eachgrep
to different files, and pipe all of the results throughless
, try:The results of the
ls -A
will be "piped" into bothgrep
s. The filehidden-files
will have the contents from the output of the firstgrep
, andnormal-files
will have the results of the secondgrep
.All of the files will be shown in the pagerEDIT: what you see inless
.less
is the same exact output ofls -A
, not the result of thegrep
s. If you want to modify the output fromls -A
toless
, (e.g. swapping the order so normal files are listed before hidden ones) then try this:Without
>/dev/null
, the output ofgrep
s would be appended to the output ofls -A
instead of replacing it.source