利用 while read 循环中的变量

3
在我的Bash脚本中,我使用while read循环和一个名为fv()的辅助函数:
fv() {
    case "$1" in
    out) echo $VAR
    ;;
    *  ) VAR="$VAR $1"
    ;; 
    esac
}

cat "$1" | while read line
    do
        ...some processings...
        fv some-str-value
    done

echo "`fv out`"

希望我能从while read循环中提取出有价值的内容,并将其存储在变量中,以便在脚本的其他部分中访问。 但是上面的片段是无用的,因为我没有得到任何输出。
有没有简单的方法解决这个问题 - 将此循环的输出字符串存储在变量中,以便在脚本的其他部分中访问 - 而不必重新格式化我的脚本?
3个回答

5
由于没有人向您解释为什么您的代码不起作用,我来解释一下。
当您使用cat "$1" |时,您使该循环在子shell中执行。在该子shell中使用的VAR变量始于主脚本中VAR的副本,对其进行的任何更改都限于该副本(子shell的范围),不会影响脚本的原始VAR。通过删除无用的cat使用,您可以删除管道,因此循环在主shell中执行,因此它可以(并且确实)更改正确的VAR副本。

感谢您的解释。一开始我很惊讶为什么我的循环内变量会被重置。后来我在SO上发现,这是由于子shell执行造成的。然后我想创建这个辅助函数,并在其中创建变量,而不是在循环中创建变量,从中输出值,正如我发布的片段所示。但我仍然不清楚的是,为什么这个外部函数fv(),在那里我创建变量,会受到这个子shell循环的影响,但我想象它被淹没在子shell中,因为它是从那里调用的。 - theta
函数在当前 shell 中执行,而不是子 shell 中执行。这意味着它们不仅可以看到它们被调用时的环境,还可以在那里修改它。 - Kevin

4

while read line ; do ... ; done < $1 替换你的 while 循环:

#!/bin/bash

function fv
{
    case "$1" in
    out) echo $VAR
    ;;
    *  ) VAR="$VAR $1"
    ;; 
    esac
}

while read line
    do
        fv "$line\n"
    done < "$1"

echo "$(fv out)"

1

停止管道读取。

done < "$1"

抱歉,我是Linux新手,无法解密您的消息。您能详细说明一下吗? - theta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接