0

I am ashamed to ask such a basic question, but it seems I have a major flaw in my understanding of pipes. I read this:

Do 'cat foo.txt | my_cmd' and 'my_cmd < foo.txt' accomplish the same thing?

and quite a few other posts, but I cannot fathom why the mentioned statement doesn't print the contents of foo.txt. Originally, I had tried

cat /etc/passwd | cut -d: -f1 | sort | echo

and eventually reduced the problem to what is listed. Interestingly, if I leave out the pipe and echo at the end everything works mostly well- although I didn't want newlines. I can also

cut -d: -f1 < /etc/passwd  | sort 

and get the same result (also unfortunately with newlines.) Maybe echo doesn't accept stdin? The man page doesn't mention it either way. It seems like a fairly useful addition to its functionality, but I guess it could make things more complicated if both stdin and arguments were supplied.

I know I'm being braindead about this. Theres no rush in answering this- I'm just curious. Thanks for your time!

yolenoyer
  • 8,797
  • 2
  • 27
  • 61
Yeshua
  • 1
  • 1
  • Standard input and command arguments are not generally interchangeable. `echo` prints what it receives as arguments, not what it receives as stdin. My answer [here](https://superuser.com/questions/600253/why-is-xargs-necessary/600273#600273) might help. (Or it might just confuse things further, but hopefully not.) – Gordon Davisson Dec 06 '20 at 06:30
  • Thanks Gordon. The main take-aways I got were "xargs can be thought of as converting STDIN-style input to arguments:" and echo actually does more-or-less the opposite. Its sort of crazy how many projects I've managed to complete without even understanding what I was actually doing, just following idioms taught to be by example. – Yeshua Dec 06 '20 at 18:00

2 Answers2

1

echo does not read stdin - that's cat's job.

As you've discovered, simply remove the | echo from your pipelines.

Gereon
  • 17,258
  • 4
  • 42
  • 73
0

Just to add some precisions.

About echo:

  • echo will never read stdin, as you can see:

    ~ $ echo HI
    HI
    ~ $ echo HI | echo LOW
    LOW
    ~ $ echo HI | echo LOW | cat
    LOW
    ~ $ echo HI | cat | echo LOW
    LOW
    
  • echo is just aimed to output the characters that you give as parameters.

  • So, piping echo like this: any_command | echo is totally useless.

About cat:

  • cat will always read stdin, unless you give it a filename, eg:
 Comments      | Shell
---------------+-------------------------------------------------------------
               | ~ $ cat poem.txt
               | My super poem
               | ~ $ cat poem.txt | cat | cat
               | My super poem
               | ~ $ echo HI | cat           # Read stdin because no filename
               |                             # is given
               | HI
               | ~ $ echo HI | cat poem.txt  # A filename is given, so don't
               |                             # take stdin into account
               | My super poem
               | ~ $ cat poem.txt | echo     # echo is not mean to be piped
               |
               | ~ $ cat poem.txt | echo HI  # echo is not mean to be piped
               | HI
               | ~ $ cat  # if no pipe or filename is given to cat, then a basic
               |          # interactive mode is proposed, thanks to the shell
[interactive]  | 1234
[cat response] | 1234
[interactive]  | Leave this hell by hitting Ctrl-D...
[cat response] | Leave this hell by hitting Ctrl-D...
[hit Ctrl-D]   |
               | ~ $ cat > new-poem.txt
[interactive]  | Looking at stars everyday
[interactive]  | So nice
[hit Ctrl-D]   |
               | ~ $ cat new-poem.txt
               | Looking at stars everyday
               | So nice
yolenoyer
  • 8,797
  • 2
  • 27
  • 61