bash 将变量的值传播到循环外
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7390497/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Propagate value of variable to outside of the loop
提问by masuch
dpkg --list |grep linux-image |grep "ii " | while read line
do
arr=(${line})
let i=i+1
_constr+="${arr[2]} "
done
echo $i
echo ${_constr}
The echo statements outside of the loop do not display the expected variables.
循环外的 echo 语句不显示预期变量。
How should I make the contents of the variable propagate outside the loop?
我应该如何使变量的内容在循环外传播?
回答by sorpigal
The problem is the pipe, not the loop. Try it this way
问题是管道,而不是循环。试试这个方法
let i=0
declare -a arr
while read -r line ; do
arr=(${line})
let i=i+1
_constr+="${arr[2]} "
done < <(dpkg --list |grep linux-image |grep "ii ")
echo $i
echo ${_constr}
You should also pre-declare globals for clarity, as shown above.
为清楚起见,您还应该预先声明全局变量,如上所示。
Pipes are executed in a subshell, as noted by Blagovest in his comment. Using process substitution instead(this is the < <(commands)syntax) keeps everything in the same process, so changes to global variables are possible.
正如 Blagovest 在他的评论中所指出的那样,管道在子外壳中执行。使用进程替换(这是< <(commands)语法)将所有内容保留在同一进程中,因此可以更改全局变量。
Incidentally, your pipeline could be improved as well
顺便说一句,您的管道也可以改进
dpkg --list |grep '^ii.*linux-image'
One less invocation of grepto worry about.
少一个grep担心的调用。
回答by Shawn Chin
This somewhat by-passes your question (and it's a good question), but you can achieve the same results using simply:
这在某种程度上绕过了您的问题(这是一个好问题),但是您可以使用简单的方法获得相同的结果:
_constr=($(dpkg --list | awk '/^ii.*linux-image/{print }'))
The ($(cmd))construct initialises a bash array using the output of the command within.
该($(cmd))构造使用其中的命令的输出初始化一个 bash 数组。
[me@home]$ echo ${_constr[*]}
linux-image-2.6.35-22-generic linux-image-2.6.35-28-generic linux-image-generic
[me@home]$ echo ${_constr[2]}
linux-image-generic
and you can get the number of elements using ${#_constr[*]}.
并且您可以使用${#_constr[*]}.
[me@home]$ echo ${#_constr[*]}
3
回答by forivall
Alternatively, you can move the echo statements inside the subshell:
或者,您可以在子外壳内移动 echo 语句:
dpkg --list |grep linux-image |grep "ii " | (
let i=0
declare -a arr
while read line
do
arr=(${line})
let i=i+1
_constr+="${arr[2]} "
done
echo $i
echo ${_constr}
)
Note the insertion of the parenthesis to explicitly define where the subshell begins and ends.
请注意插入括号以明确定义子外壳的开始和结束位置。

