Monday, August 22, 2011

bash bug with read

The echo pipe read a bug

so, a frequently reported bug is this one:

$ echo hi | read a; echo $a

and the result is not "hi", is nothing !

So why ?

Whenever you see a pipe in a command line you should understand that a subprocess has implicitly been created. That must exist in order for there to be an un-named pipe. Remember that the pipe in an "interprocess communication mechanism" (IPC). Therefore we have to have multiple processes  between/among which to communicate.

In most shells (including Bourne, older Korn, bash, and pdksh) the subprocess was created to handle the commands on the right of the pipe operator. Thus our 'read' command (in the examples below) is happening in a subshell. Naturally that shell exits after completing its commands; and the variables it  has set are lost. Naturally the subshell can only affect its own copies for any shell and environment variables.

With newer versions of ksh and zsh we find that the subshell is usually created on the left of the pipe.

This allows us to use commands like "echo foo bar  bang | read a b c ; echo $a $b $c" with that effect that most people would expect.

Note that the follow will work under bash, pdksh, etc: "echo foo bar  bang | ( read a b c ; echo $a $b $c )"

(We have to do everything with our variables within the subshell).

so, the solution is:

$ echo hi | ( read a; echo $a )

No comments: