Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Edit : original title was "read fails in bash"

With ksh I'm using read as a convenient way to separate values:

  $ echo 1 2 3 4 5 | read a b dump
  $ echo $b $a 
  2 1

But it fails in bash :

  $ echo 1 2 3 4 5 | read a b dump
  $ echo $b $a 


I didn't find a reason in the man page why it fails, any idea ?

share|improve this question
This is discussed (somewhat obscurely) in page 024 of Greg’s Bash FAQ. – Scott Jul 11 '14 at 18:27
up vote 10 down vote accepted

bash runs the right-hand side of a pipeline in a subshell context, so changes to variables (which is what read does) are not preserved — they die when the subshell does, at the end of the command.

Instead, you can use process substitution:

$ read a b dump < <(echo 1 2 3 4 5)
$ echo $b $a
2 1

In this case, read is running within our primary shell, and our output-producing command runs in the subshell. The <(...) syntax creates a subshell and connects its output to a pipe, which we redirect into the input of read with the ordinary < operation. Because read ran in our main shell the variables are set correctly.

As pointed out in a comment, if your goal is literally to split a string into variables somehow, you can use a here string:

read a b dump <<<"1 2 3 4 5"

I assume there's more to it than that, but this is a better option if there isn't.

share|improve this answer
Or even read a b dump <<< '1 2 3 4 5'. – choroba Jul 11 '14 at 10:41
Thank you to all, btw I noted that mksh (on cygwin) is doing the same as bash. – Emmanuel Jul 11 '14 at 10:56

This is not a bash bug as POSIX allows both bash and ksh behaviors, leading to the unfortunate discrepancy you are observing.


Additionally, each command of a multi-command pipeline is in a subshell environment; as an extension, however, any or all commands in a pipeline may be executed in the current environment. All other commands shall be executed in the current shell environment.

However, with bash 4.2 and newer, you can set the lastpipe option in non interactive scripts to get the expected result, eg:


echo 1 2 3 4 5 | read a b dump
echo before: $b $a 
shopt -s lastpipe
echo 1 2 3 4 5 | read a b dump
echo after: $b $a 


after: 2 1
share|improve this answer
+1 thank you for the "lastpipe" info. sorry for the delay – Emmanuel Jul 29 '14 at 14:47

I've classified this as a bug in bash and ash. I have a patch for an old version of ash lying around that fixes it. Nobody seemed to care.

Please note that commercial ksh (where I cut my teeth) does not have this bug.

share|improve this answer
I agree, I don't see the point to fork a shell to run a build in function. – Emmanuel Jul 11 '14 at 18:41
It cannot be classified as a bug given the fact bash behavior complies with both its own documentation and the POSIX standard. – jlliagre Jul 12 '14 at 9:35

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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