Shell scripting input redirection oddities

2019-02-06 00:29发布

Can anyone explain this behavior? Running:

#!/bin/sh
echo "hello world" | read var1 var2
echo $var1
echo $var2

results in nothing being ouput, while:

#!/bin/sh
echo "hello world" > test.file
read var1 var2 < test.file
echo $var1
echo $var2

produces the expected output:

hello
world

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.

9条回答
叛逆
2楼-- · 2019-02-06 00:53

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.

Execute this command

$ echo $$;cat | read a
10637

and use pstree -p to look at the running processes, you will see an extra shell hanging off of your main shell.

    |                       |-bash(10637)-+-bash(10786)
    |                       |             `-cat(10785)
查看更多
Juvenile、少年°
3楼-- · 2019-02-06 00:57

The post has been properly answered, but I would like to offer an alternative one liner that perhaps could be of some use.

For assigning space separated values from echo (or stdout for that matter) to shell variables, you could consider using shell arrays:

$ var=( $( echo 'hello world' ) )
$ echo ${var[0]}
hello
$ echo ${var[1]}
world

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).

That way you can have as many parameters as you want assigned to the relevant array index.

查看更多
Luminary・发光体
4楼-- · 2019-02-06 01:07
read var1 var2 < <(echo "hello world")
查看更多
登录 后发表回答