如何pipe道input到Bash while循环,并在循环结束后保存variables

Bash允许使用: cat <(echo "$FILECONTENT")

Bash也允许使用: while read i; do echo $i; done </etc/passwd while read i; do echo $i; done </etc/passwd

结合前面两个这个可以使用: echo $FILECONTENT | while read i; do echo $i; done echo $FILECONTENT | while read i; do echo $i; done

最后一个问题是,它创build子shell,并且在while循环结束variables之后, i不能再被访问。

我的问题是:

如何实现这样的事情: while read i; do echo $i; done <(echo "$FILECONTENT") while read i; do echo $i; done <(echo "$FILECONTENT") while read i; do echo $i; done <(echo "$FILECONTENT")或换句话说:我怎样才能确保i生存的循环?

请注意,我知道附加while语句到{}但是这并不能解决这个问题(假设你想在函数中使用while循环并返回variables)

stream程replace的正确表示法是:

 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分组操作,本身不创build子shell。 在这种情况下,它们是pipe道的一部分,因此作为子shell运行,但这是因为| ,而不是{ ... } 。 你在问题中提到这一点。 AFAIK,你可以在这些函数内部做一个返回。


Bash还提供了内置的shopt ,其众多选项之一是:

lastpipe

如果设置,并且作业控制未激活,则shell将运行当前shell环境中未在后台执行的pipe道的最后一个命令。

因此, 在脚本中使用类似的东西可以在循环之后得到修改后的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 

在命令行执行此操作通常会遇到“作业控制未激活”(即在命令行中作业控制处于活动状态)的情况。 不使用脚本进行testing失败。

另外,正如Gareth Rees在他的回答中所指出的,你有时可以使用这里的string :

 while read i; do echo $i; done <<< "$FILECONTENT" 

这不需要shopt ; 您可以使用它来保存一个进程。

Jonathan Leffler解释了如何使用stream程replace来做你想要的,但另一种可能性是使用这里的string

 while read i; do echo "$i"; done <<<"$FILECONTENT" 

这节省了一个过程。