阻止 bash 函数破坏全局变量

阻止 bash 函数破坏全局变量

以下是重新配置 grub 的 bash 脚本的摘录

    OLD="/etc/default/grub"
    NEW="/tmp/default.grub"
    SEC="1"

    cp "$OLD" "$NEW" || { >&2 echo "Couldn't copy $OLD" && exit 1; }

    sed -i "s/GRUB_TIMEOUT=[0-9]\+/GRUB_TIMEOUT=3/$SEC" "$NEW"

    cp_if_change_confirmed "$NEW" "$OLD"

    diff "$OLD" "$NEW" >/dev/null 2>&1 && \
    {
        CFG="$NEW.made"

        grub2-mkconfig --output="$CFG"

        echo "made $CFG from $NEW"

        cp_if_change_confirmed "$CFG" "/boot/grub2/grub.cfg"

        echo rm "$CFG"
        rm "$CFG"
    }

    echo rm "$NEW"
    rm "$NEW"

这些最终echorm行输出

rm /tmp/default.grub.made
rm /tmp/default.grub.made
rm: cannot remove ‘/tmp/default.grub.made:‘ No such file or directory

以某种方式NEW被赋予了 的值CFG

查看cp_if_change_confirmedbash 函数,它包含

NEW="$1"

我想这解释了问题所在——这些变量的范围不够有限。

但这是一个维护问题——我需要能够包含第三方函数并且知道它们不会破坏父脚本中的值。

我可以在 bash 中执行此操作吗?或者这是一个无望的情况,我只需要对变量名保持警惕或使用真正的语言?

答案1

使用local。请注意,bash 有仅有的函数作用域(类似varJavaScript),而不是块作用域。

myfunc() {
    local foo bar=$1 baz=$2
    foo=/tmp/$bar
    echo "value inside: $foo, $bar"
}
foo=123 bar=234
myfunc quux
echo "value outside: $foo, $bar"

如果你有一个不需要的区块任何持久性,你可以使用以下命令调用子 shell ( ... )

foo=123
( foo=345; echo "value inside: $foo" )
echo "value outside: $foo"

请注意,子 shell 具有 fork() 的全部开销 - 它们是独立的进程。此外,它们不允许您选择要本地化的变量 - 要么全部,要么全部。

相关内容