In the example function a
, I capture the input from a pipe as follows:
function a() {
if [ -t 1 ]; then
read test
echo "$test"
fi
# If $1 has a value, print it
if [[ -n "$1" ]]; then
echo "$1"
fi
}
called as follows:
echo "hey " | a "hello"
produces the output:
hey
hello
I was inspired by this answer, however a quote after the snippet has me concerned:
But there's no point - your variable assignments may not last! A pipeline may spawn a subshell, where the environment is inherited by value, not by reference. This is why read doesn't bother with input from a pipe - it's undefined.
I'm not sure I understand this - attempting to create subshells yielded the output I expected:
function a() {
(
if [ -t 1 ]; then
read test
echo "$test"
fi
if [[ -n "$1" ]]; then
echo "$1"
fi
)
}
And in the method call:
(echo "hey") | (a "hello")
still yields:
hey
hello
So what is meant by your variable assignments may not last! A pipeline may spawn a subshell, where the environment is inherited by value, not by reference.? Is there something that I've misunderstood?
Try this:
echo test | read myvar
echo $myvar
You might expect that it will print test
, but it doesn't, it prints nothing. The reason is that bash will execute the read myvar
in a subshell process. The variable will be read, but only in that subshell. So in the original shell the variable will never be set.
On the other hand, if you do this:
echo test | { read myvar; echo $myvar; }
or this
echo test | (read myvar; echo $myvar)
you will get the expected output. This is what happens with your code.