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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 00:45:53  来源:igfitidea点击:

Propagate value of variable to outside of the loop

bashvariablesloops

提问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.

请注意插入括号以明确定义子外壳的开始和结束位置。