ls | echo, I got blank, why can't echo take the 2nd seat in a pipeline?
Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
ls | echo, I got blank, why can't echo take the 2nd seat in a pipeline?
I have searched "Linux newbie" for "echo" in titles, but no answer to my question is found.
when I learnt pipeline of Bash, I tried:
ls | echo
, which I would like to see the same result of the "ls".
The output of "ls" is redirected to the 2nd command "echo" and be its argument, that's what I thought.
But the output is blank. If I use:
echo $(ls)
instead, I get what I want, like this,
echo $(ls)
a.txt
b.txt
So, does someone know why echo can't take the output of the previous command in a pipeline?
echo doesn't read input from stdin, so you can't pipe data into it. If you want to transform stdin to arguments for echo, use xargs, like this:
Code:
ls | xargs echo
xargs reads input from stdin, and transforms it to a list of arguments which it passes to echo. Now, this isn't a very useful thing to do. The shell will expand * to the list of [non-hidden] files in the current working directory, so you can get the same effect by doing:
Code:
echo *
Note that the shell expands the wild-card to a list before passing the list to the echo command. This is a frequently-held misconception which many people have - that the program (in this case echo) sees the wild-card and expands it itself - this used to happen in DOS, but NOT in Unix shells. The shell pre-expands the wild-card and passes that list to the command. You can force the shell to treat the wild-card as a literal string by quoting it, or escaping it with a backslash:
Code:
echo \*
Which will simply print a * character. Similarly, if you do this:
Code:
ls -l '*'
ls will receive the literal * character. ls doesn't know how to expand the wild-card, and will simply try to list the details of the file with the name *, which probably won't exist, and you'll get a message like this:
Code:
ls: *: No such file or directory
If you want a program which reads stdin and prints what it read to stdout, you're looking for cat
Code:
ls |cat
One last thing to note: piping the output of ls into programs will gave subtly different behaviour from allowing ls to print it's output to the terminal. ls prints in columns when it is outputting to th terminal, but one filename per line when output is re-directed or piped into another program. It also supresses colour output in these cases.
One last thing to note: piping the output of ls into programs will gave subtly different behaviour from allowing ls to print it's output to the terminal. ls prints in columns when it is outputting to th terminal, but one filename per line when output is re-directed or piped into another program. It also supresses colour output in these cases.
However, you can force printing in columns with the -C option and colour with --color=always.
echo was originally an external command, and that command had/has it's own manual page. Because it is something which tends to be used pretty frequently, and is simple, it was adopted by more modern shells as an internal command (this makes it more efficient to call since there is no spawning of a new process for the external program).
This leads to the rather confusing situation with modern distros where you have both the program in /bin/echo, with it's own manual page, but when you type "echo something" in a bash shell, the bash-internal is used, and the behaviour is sligtly different to that which the manual page describes:
Code:
$ echo --version
--version
$ /bin/echo --version
echo (GNU coreutils) 5.96
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software. You may redistribute copies of it under the terms of
the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
There is NO WARRANTY, to the extent permitted by law.
Written by FIXME unknown.
Despite this, the behaviour is close enough that for most uses it doesn't matter. The /bin/echo may still get used. The only example I can think of is if your distro uses a very cut down shell for start-up scripts which doesn't include any un-necessary internals. Ubuntu dapper uses the "dash" shell for init, although I think in this case echo is built-in. Does anyone out there know a shell which is distributed with a common Linux which doesn't have echo built in?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.