while 会在 bash 中生成一个子shell吗?

Adi*_*a K 14 bash

有人可以解释为什么这个脚本没有产生我期望的输出吗?

 #!/bin/bash
 #

var=0

ls -1 /tmp| while read file
do
     echo $file
     var=1
done

echo "var is $var"
Run Code Online (Sandbox Code Playgroud)

我得到一个文件列表,然后是 var is 0

为什么 var 不等于 1?是不是因为 while 循环产生了一个子壳?

PSk*_*cik 15

管道可以。您可以自己检查,例如通过$BASHPID从 while 循环的内部和外部打印或执行以下操作:

ls | while read file; do
    sleep 100;
done
Run Code Online (Sandbox Code Playgroud)

,停止C-Z并检查psps --forest之后查看终端会话中的进程树。

您可以通过稍微不同的“管道”来避免子shell:

var=0
while read file
do 
  echo $file; var=1
done < <(ls -1 /tmp/)

echo $var #=> 1
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢您的演示和解决方案,但我认为您的第一句话不准确,while 循环本身不会产生子外壳,否则您的解决方案也不起作用 (3认同)

fed*_*qui 6

另一个好的答案已经解释了未保留变量值的原因。如果您愿意,可以在我在管道中的循环中设置变量中阅读有关此主题的有趣文章为什么它们在循环终止后消失?或者,为什么我不能通过管道读取数据?.

我只想展示另一种遍历文件的方法,这样您就根本不用解析ls

for file in /tmp/*
do
   echo "$file"
   var=1
done
Run Code Online (Sandbox Code Playgroud)

就是这样!只需/tmp/*展开以提供目录中的所有内容/tmp

我猜你的脚本只是一些虚拟代码,而不是真正的代码。但是如果您碰巧正在检查是否/tmp包含某些值,您也可以说:

shopt -s nullglob
r=(/tmp/*)
Run Code Online (Sandbox Code Playgroud)

然后计算数组中的元素:

echo ${#r[@]}
Run Code Online (Sandbox Code Playgroud)

请注意,如果没有与此模式匹配的内容,我曾经shopt -s nullblog阻止/tmp/*扩展到文字字符串/tmp/*


归档时间:

查看次数:

6265 次

最近记录:

10 年,11 月 前