read command in sh works if I redirect file1 as standard input like

$ cat file1
first second
$ read u v <file1
$ echo $u
$ echo $v

However, if I redirect standard output from echo like

$ echo first second | read a b
$ echo $a

It does not work. I thought read gets standard input from pipe in the second case. Why am I wrong? Thank you.


1 Answer 1


In your first example :

read and 'echo" being shell built-in commands, they will be executed by the interactive shell you are typing commands in (the same process) and therefore the result of these commands concern the environment of your running shell.

Hence when returning from the read instruction, you are still in the same shell perfectly aware of u and v variables values.

In your second example :

Even if the command is built-in, the pipe forces your interactive shell to fork a child process. In this occurrence, it will fire a subshell that will execute the read command and update its own environment (assign a value to u and v variables) without influencing the environment of its parent.

Therefore when the read has completed, the subshell terminates and you come back to your interactive shell which is totally unaware of u and v variable values as set by its child.

  • 1
    Note that while in A | B, A and B have to run in different processes, then don't have to both run in child processes. In ksh, zsh or fish, they don't. Jun 12 at 15:17

Not the answer you're looking for? Browse other questions tagged or ask your own question.