过程替换的正确表示法是:
while read i; do echo $i; done < <(echo "$FILECONTENT")
i
当循环终止时,循环中分配的最后一个值可用。另一种选择是:
echo $FILECONTENT |
{
while read i; do echo $i; done
...do other things using $i here...
}
大括号是 I/O 分组操作,本身不会创建子 shell。在这种情况下,它们是管道的一部分,因此作为子外壳运行,但这是因为 . 而|
不是{ ... }
. 你在问题中提到了这一点。AFAIK,您可以从函数内部的这些内部进行返回。
Bash 还提供了shopt
内置函数,它的众多选项之一是:
lastpipe
如果设置,并且作业控制未激活,则 shell 将在当前 shell 环境中运行未在后台执行的管道的最后一个命令。
因此,在脚本中使用类似这样的东西会使修改sum
后的循环在循环后可用:
FILECONTENT="12 Name
13 Number
14 Information"
shopt -s lastpipe # Comment this out to see the alternative behaviour
sum=0
echo "$FILECONTENT" |
while read number name; do ((sum+=$number)); done
echo $sum
在命令行执行此操作通常会违反“作业控制未激活”(即,在命令行,作业控制已激活)。在不使用脚本的情况下对此进行测试失败。
此外,正如Gareth Rees在他的回答中所指出的,您有时可以使用此处的字符串:
while read i; do echo $i; done <<< "$FILECONTENT"
这不需要shopt
;您可以使用它来保存进程。