将变量的值传播到循环外部

发布于 2024-12-03 22:38:28 字数 228 浏览 0 评论 0原文

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 语句不显示预期的变量。

我应该如何使变量的内容传播到循环之外?

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.

How should I make the contents of the variable propagate outside the loop?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浅暮の光 2024-12-10 22:38:28

问题出在管道上,而不是环路上。尝试这种方式

let i=0
arr=()
_constr=

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}"

管道是在子 shell 中执行的,正如 Blagovest 在他的评论中指出的那样。使用进程替换(这是<<(commands) 语法)将所有内容保持在同一进程中,因此可以更改全局变量。

顺便说一句,您的管道也可以得到改进,

dpkg --list | grep '^ii.*linux-image'

减少一次需要担心的 grep 调用。

The problem is the pipe, not the loop. Try it this way

let i=0
arr=()
_constr=

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}"

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.

Incidentally, your pipeline could be improved as well

dpkg --list | grep '^ii.*linux-image'

One less invocation of grep to worry about.

兔姬 2024-12-10 22:38:28

这在某种程度上绕过了您的问题(这是一个好问题),但是您可以简单地使用以下方法获得相同的结果:

 _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

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 $2}'))

The ($(cmd)) construct initialises a bash array using the output of the command within.

[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[*]}.

[me@home]$ echo ${#_constr[*]}
3
输什么也不输骨气 2024-12-10 22:38:28

或者,您可以在子 shell 内移动 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 的开始和结束位置。

Alternatively, you can move the echo statements inside the subshell:

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文