将变量的值传播到循环外[重复]
Posted
技术标签:
【中文标题】将变量的值传播到循环外[重复]【英文标题】:Propagate value of variable to outside of the loop [duplicate] 【发布时间】:2011-11-15 11:19:03 【问题描述】: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
循环外的 echo 语句不显示预期的变量。
我应该如何让变量的内容在循环外传播?
【问题讨论】:
请记住,while
循环在单独的进程中运行,这就是您看不到更改的变量的原因。
【参考方案1】:
问题是管道,而不是循环。试试这个方法
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
为了清楚起见,您还应该预先声明全局变量,如上所示。
正如 Blagovest 在他的评论中指出的那样,管道在子外壳中执行。使用process substitution instead(这是< <(commands)
语法)将所有内容保持在同一进程中,因此可以更改全局变量。
顺便说一句,您的管道也可以改进
dpkg --list |grep '^ii.*linux-image'
不用担心调用grep
。
【讨论】:
在 bash 3.x 中,循环的最后一行应该是done <<<`commands`
@Ida:这样做有什么好处?这样做会失败:子shell将执行并在自己的行上返回每个结果,然后将其分解为单个字符串并立即馈送到read
,它将读取直到第一个嵌入的换行符,循环一次然后@ 987654328@,没有更多的输入来处理,将终止。这不是你想要的。之后只有来自查询的第一个包版本会在 _constr
中。 bash 3.x 可以理解 <()
构造。
+1 + done[space]
【参考方案2】:
这在某种程度上绕过了您的问题(这是一个很好的问题),但是您可以简单地使用以下方法获得相同的结果:
_constr=($(dpkg --list | awk '/^ii.*linux-image/print $2'))
($(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
你可以使用$#_constr[*]
获取元素的数量。
[me@home]$ echo $#_constr[*]
3
【讨论】:
这确实是正确的做法。我没有要测试的 Debian 盒子,否则我会提出同样的建议。【参考方案3】:或者,您可以将 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
)
注意插入括号以明确定义子shell的开始和结束位置。
【讨论】:
以上是关于将变量的值传播到循环外[重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何将动作从 SKScene 组件传播到 UIViewController
同时不改变循环外变量的值。我需要制作一种以随机方式对数组进行洗牌的方法。 (C#请)[重复]