<p>Can anyone explain this behavior?
Running:</p>

<pre><code>#!/bin/sh
echo "hello world" | read var1 var2
echo $var1
echo $var2
</code></pre>

<p>results in nothing being ouput, while:</p>

<pre><code>#!/bin/sh
echo "hello world" &gt; test.file
read var1 var2 &lt; test.file
echo $var1
echo $var2
</code></pre>

<p>produces the expected output:</p>

<pre><code>hello
world
</code></pre>

<p>Shouldn't the pipe do in one step what the redirection to test.file did in the second example?  I tried the same code with both the dash and bash shells and got the same behavior from both of them.</p>

[{'answer_id': 2764, 'author': 'Mark Harrison', 'author_id': 116, 'author_profile': 'https://Stackoverflow.com/users/116', 'pm_score': 3, 'selected': False, 'text': "<p>It's because the pipe version is creating a subshell, which reads the variable into its local space which then is destroyed when the subshell exits.</p>\n\n<p>Execute this command</p>\n\n<pre><code>$ echo $$;cat | read a\n10637\n</code></pre>\n\n<p>and use pstree -p to look at the running processes, you will see an extra shell hanging off of your main shell.</p>\n\n<pre><code>    |                       |-bash(10637)-+-bash(10786)\n    |                       |             `-cat(10785)\n</code></pre>\n"}, {'answer_id': 2777, 'author': 'num1', 'author_id': 306, 'author_profile': 'https://Stackoverflow.com/users/306', 'pm_score': 3, 'selected': False, 'text': '<p>Allright, I figured it out!</p>\n\n<p>This is a hard bug to catch, but results from the way pipes are handled by the shell. Every element of a pipeline runs in a separate process. When the read command sets var1 and var2, is sets them it its own subshell, not the parent shell. So when the subshell exits, the values of var1 and var2 are lost. You can, however, try doing \n</p>\n\n<pre><code>var1=$(echo "Hello")\necho var1\n</code></pre>\n\n<p>which returns the expected answer. Unfortunately this only works for single variables, you can\'t set many at a time. In order to set multiple variables at a time you must either read into one variable and chop it up into multiple variables or use something like this:</p>\n\n<pre><code>set -- $(echo "Hello World")\nvar1="$1" var2="$2"\necho $var1\necho $var2\n</code></pre>\n\n<p>While I admit it\'s not as elegant as using a pipe, it works. Of course you should keep in mind that read was meant to read from files into variables, so making it read from standard input should be a little harder.</p>\n'}, {'answer_id': 12412, 'author': 'Jon Ericson', 'author_id': 1438, 'author_profile': 'https://Stackoverflow.com/users/1438', 'pm_score': 4, 'selected': False, 'text': '<p>This has already been answered correctly, but the solution has not been stated yet.  Use ksh, not bash.  Compare:</p>\n\n<pre><code>$ echo \'echo "hello world" | read var1 var2\necho $var1\necho $var2\' | bash -s\n</code></pre>\n\n<p>To:</p>\n\n<pre><code>$ echo \'echo "hello world" | read var1 var2\necho $var1\necho $var2\' | ksh -s\nhello\nworld\n</code></pre>\n\n<p>ksh is a superior programming shell because of little niceties like this.  (bash is the better interactive shell, in my opinion.)</p>\n'}, {'answer_id': 61462, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 3, 'selected': False, 'text': "<p>The post has been properly answered, but I would like to offer an alternative one liner that perhaps could be of some use.</p>\n\n<p>For assigning space separated values from echo (or stdout for that matter) to shell variables, you could consider using shell arrays:</p>\n\n<pre><code>$ var=( $( echo 'hello world' ) )\n$ echo ${var[0]}\nhello\n$ echo ${var[1]}\nworld\n</code></pre>\n\n<p>In this example var is an array and the contents can be accessed using the construct ${var[index]}, where index is the array index (starts with 0).</p>\n\n<p>That way you can have as many parameters as you want assigned to the relevant array index.</p>\n"}, {'answer_id': 78604, 'author': 'Steve Baker', 'author_id': 13566, 'author_profile': 'https://Stackoverflow.com/users/13566', 'pm_score': 3, 'selected': False, 'text': '<pre><code>read var1 var2 &lt; &lt;(echo "hello world")\n</code></pre>\n'}, {'answer_id': 79203, 'author': 'pjz', 'author_id': 8002, 'author_profile': 'https://Stackoverflow.com/users/8002', 'pm_score': 2, 'selected': False, 'text': '<p>Try:</p>\n\n<pre><code>echo "hello world" | (read var1 var2 ; echo $var1 ; echo $var2 )\n</code></pre>\n\n<p>The problem, as multiple people have stated, is that var1 and var2 are created in a subshell environment that is destroyed when that subshell exits. The above avoids destroying the subshell until the result has been echo\'d. Another solution is:</p>\n\n<pre><code>result=`echo "hello world"`\nread var1 var2 &lt;&lt;EOF\n$result\nEOF\necho $var1\necho $var2\n</code></pre>\n'}, {'answer_id': 98945, 'author': 'flabdablet', 'author_id': 14845, 'author_profile': 'https://Stackoverflow.com/users/14845', 'pm_score': 4, 'selected': False, 'text': '<pre><code>#!/bin/sh\necho "hello world" | read var1 var2\necho $var1\necho $var2\n</code></pre>\n\n<p>produces no output because pipelines run each of their components inside a subshell.  Subshells <em>inherit copies</em> of the parent shell\'s variables, rather than sharing them.  Try this:</p>\n\n<pre><code>#!/bin/sh\nfoo="contents of shell variable foo"\necho $foo\n(\n    echo $foo\n    foo="foo contents modified"\n    echo $foo\n)\necho $foo\n</code></pre>\n\n<p>The parentheses define a region of code that gets run in a subshell, and $foo retains its original value after being modified inside them.</p>\n\n<p>Now try this:</p>\n\n<pre><code>#!/bin/sh\nfoo="contents of shell variable foo"\necho $foo\n{\n    echo $foo\n    foo="foo contents modified"\n    echo $foo\n}\necho $foo\n</code></pre>\n\n<p>The braces are purely for grouping, no subshell is created, and the $foo modified inside the braces is the same $foo modified outside them.</p>\n\n<p>Now try this:</p>\n\n<pre><code>#!/bin/sh\necho "hello world" | {\n    read var1 var2\n    echo $var1\n    echo $var2\n}\necho $var1\necho $var2\n</code></pre>\n\n<p>Inside the braces, the read builtin creates $var1 and $var2 properly and you can see that they get echoed.  Outside the braces, they don\'t exist any more.  All the code within the braces has been run in a subshell <em>because it\'s one component of a pipeline</em>.</p>\n\n<p>You can put arbitrary amounts of code between braces, so you can use this piping-into-a-block construction whenever you need to run a block of shell script that parses the output of something else.  </p>\n'}, {'answer_id': 609915, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 3, 'selected': False, 'text': '<p>My take on this issue (using Bash):</p>\n\n<pre><code>read var1 var2 &lt;&lt;&lt; "hello world"\necho $var1 $var2\n</code></pre>\n'}, {'answer_id': 11668996, 'author': 'chepner', 'author_id': 1126841, 'author_profile': 'https://Stackoverflow.com/users/1126841', 'pm_score': 5, 'selected': True, 'text': '<p>A recent addition to <code>bash</code> is the <code>lastpipe</code> option, which allows the last command in a pipeline to run in the current shell, not a subshell, when job control is deactivated.</p>\n\n<pre><code>#!/bin/bash\nset +m      # Deactiveate job control\nshopt -s lastpipe\necho "hello world" | read var1 var2\necho $var1\necho $var2\n</code></pre>\n\n<p>will indeed output</p>\n\n<pre><code>hello\nworld\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/2732', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/75/']