Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Piping not working with echo command [duplicate]

Tags:

bash

echo

When I run the following Bash script, I would expect it to print Hello. Instead, it prints a blank line and exits.

echo 'Hello' | echo 

Why doesn't piping output from echo to echo work?

like image 868
Elliot A. Avatar asked Jan 31 '16 17:01

Elliot A.


People also ask

Does echo read from stdin?

echo prints all of its arguments. It does not read from stdin . So the second echo prints all of its arguments (none) and exits, ignoring the Hello on stdin . or $ echo Hello | xargs echo which is equivalent to echo Hello | xargs by default.

What does @echo do command?

The echo command is a built-in Linux feature that prints out arguments as the standard output. echo is commonly used to display text strings or command results as messages. In this tutorial, you will learn about all the different ways you can use the echo command in Linux.

How do you pipe a command output?

The > symbol is used to redirect output by taking the output from the command on the left and passing as input to the file on the right.

How do you connect multiple command pipes?

Use parentheses ()'s to combine the commands into a single process, which will concatenate the stdout of each of them.


2 Answers

echo prints all of its arguments. It does not read from stdin. So the second echo prints all of its arguments (none) and exits, ignoring the Hello on stdin.

For a program that reads its stdin and prints that to stdout, use cat:

$ echo Hello | cat Hello 
like image 103
iobender Avatar answered Sep 21 '22 12:09

iobender


In this case the pipe you are using are more correctly known as anonymous pipes, because they have no name (there are also named pipes). Anonymous pipes only work between related processes, for example processes with the same parent.

Pipes are part of the IO system resulting from the C runtime-library. These streams are buffered (there is an exception) by default. Basically a pipe is just connecting the output buffer from one process to the input buffer of another.

The first three streams used (called file descriptors) are numbered 0, 1, and 2. The first, 0, is known as standard input, or stdin (the name used in C). By default this is connected to the keyboard, but it can be redirected either using the < symbol or the program name being on the right side of a pipe.

The second, 1, is known as standard output, or stdout. By default this is connected to the terminal screen, but can be redirected by using the > symbol or the program name being on the left side of a pipe.

So:

echo 'Hello' | echo 

takes the standard output from echo and passes it to the standard input of echo. But echo does not read stdin! So nothing happens.

Filter programs process the filenames specified on the command-line. If no filenames are given then they read stdin. Examples include cat, grep, and sed, but not echo. For example:

echo 'Hello' | cat 

will display 'Hello', and the cat is useless (it often is).

echo 'Hello' | cat file1 

will ignore the output from echo and just display the contents of file1. Remember that stdin is only read if no filename is given.

What do you think this displays?

echo 'Hello' | cat < file1 file2 

and why?

Finally, the third stream, 2, is called standard error, or stderr, and this one is unbuffered. It is ignored by pipes, because they only operate between stdin and stdout. However, you can redirect stderr to use stdout (see man dup2):

myprog 2>&1 | anotherprog 

The 2>&1 means "redirect file descriptor 2 to the same place as fie descriptor 1".

The above is normal behaviour, however a program can override all that if it wants to. It could read from file descriptor 2, for example. I have omitted a lot of other detail, including other forms of redirection such as process substitution and here documents.

like image 26
cdarke Avatar answered Sep 18 '22 12:09

cdarke