为什么bash的read命令会创建一个循环局部变量?

huangapple go评论60阅读模式
英文:

why bash read command create a loop-local variable?

问题

我编写了以下的bash脚本。read命令创建了变量`var`。
如果`$var==5`,则退出循环。

```bash
    seq 10 | while read -r var
    do
      echo "read: $var"
      if [[ $var == 5 ]]; then
        echo "break loop: $var"
        break
      fi
    done
    
    echo "after loop: $var"

这是输出结果

read: 1
read: 2
read: 3
read: 4
read: 5
break loop: 5
after loop: 

问题是:为什么循环结束后,$var 变成空的?


<details>
<summary>英文:</summary>

I wrote following bash script. The read command creates variable `var`.
if `$var==5` then break loop.
 
```bash
    seq 10 | while read -r var
    do
      echo &quot;read: $var&quot;
      if [[ $var == 5 ]]; then
        echo &quot;break loop: $var&quot;
        break
      fi
    done
    
    echo &quot;after loop: $var&quot;

Here is the output

read: 1
read: 2
read: 3
read: 4
read: 5
break loop: 5
after loop: 

My question is: why after loop, $var is empty?

答案1

得分: 2

变量不是循环局部的,与read和循环相关的部分都是干扰项。你看到的行为是因为管道启动了一个子shell。如果你去掉管道,运行这段代码代替:

while read -r var
do
  echo "read: $var"
  if [[ $var == 5 ]]; then
    echo "break loop: $var"
    break
  fi
done < <(seq 10)

echo "after loop: $var"

那么输出将会是:

read: 1
read: 2
read: 3
read: 4
read: 5
break loop: 5
after loop: 5
英文:

The variable isn't loop-local, and everything related to read and loops here are just red herrings. The behavior you're seeing is because the pipe starts a subshell. If you get rid of the pipe and run this code instead:

    while read -r var
    do
      echo &quot;read: $var&quot;
      if [[ $var == 5 ]]; then
        echo &quot;break loop: $var&quot;
        break
      fi
    done &lt; &lt;(seq 10)
    
    echo &quot;after loop: $var&quot;

Then it will print this instead:

read: 1
read: 2
read: 3
read: 4
read: 5
break loop: 5
after loop: 5

huangapple
  • 本文由 发表于 2023年2月18日 08:57:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75490498.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定