Shell scripting input redirection oddities

前端 未结 9 2071
不思量自难忘°
不思量自难忘° 2020-12-31 00:00

Can anyone explain this behavior? Running:

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

results in nothing being o

9条回答
  •  天命终不由人
    2020-12-31 00:38

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

    produces no output because pipelines run each of their components inside a subshell. Subshells inherit copies of the parent shell's variables, rather than sharing them. Try this:

    #!/bin/sh
    foo="contents of shell variable foo"
    echo $foo
    (
        echo $foo
        foo="foo contents modified"
        echo $foo
    )
    echo $foo
    

    The parentheses define a region of code that gets run in a subshell, and $foo retains its original value after being modified inside them.

    Now try this:

    #!/bin/sh
    foo="contents of shell variable foo"
    echo $foo
    {
        echo $foo
        foo="foo contents modified"
        echo $foo
    }
    echo $foo
    

    The braces are purely for grouping, no subshell is created, and the $foo modified inside the braces is the same $foo modified outside them.

    Now try this:

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

    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 because it's one component of a pipeline.

    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.

提交回复
热议问题