gpt4 book ai didi

Bash 变量范围泄漏

转载 作者:行者123 更新时间:2023-11-29 09:11:03 24 4
gpt4 key购买 nike

通常,我看到有关人们无法从其范围之外访问变量的问题。但是,我似乎遇到了相反的情况:我看到变量仍然具有来自内部范围的值,它们之后应该放弃。例如(使 svn 别名类似于 git aliases ):

function svn() {
case $@ in
alias*) shift 1;
for i in "$@"; do
if [[ "$i" == "-t" ]];
then
j="$i,$j"
elif [[ "$i" == "-f" ]];
k="$i,$j"
fi
done

echo "i = $i"
echo "j = $j"
echo "k = $k"
;;
esac
}

我把它放在一个脚本中并获取它的源代码,所以它的功能被制成 bash 的别名(我认为)。尝试使用“-t”和“-f”的各种组合来运行它,你会看到变量“$i”、“$j”和“$k”在再次运行脚本时都保持它们的值,并且在脚本退出后,它们在 shell 中保持不变。我正在使用 Ubuntu 15.04 笔记本电脑,当我键入 Ctrl-X Ctrl-V 我的 shell 输出 GNU bash,版本 4.3.30(1)-release (x86_64- pc-linux-gnu)。

我读到的关于 bash 的所有内容都告诉我这不应该发生(诚然,我在这方面还算新手)。变量不应在脚本(或函数)退出后保持设置状态,除非您对它们使用 export,而我没有这样做。那为什么会这样呢?

最佳答案

有两种不同的现象在起作用:

  1. 当变量被导出时,它们被复制到子进程的环境中。不传递非导出变量。变量不会导出,除非您明确使用 export 将它们标记为导出。

     export LESS_OPTIONS=-R   # export so `less` sees this variable
    less

    不要将它与范围混淆,后者是不同的。

  2. 默认情况下,内部函数变量具有全局作用域。您必须使用 local 关键字来声明局部变量。否则,像 for i in "$@" 这样的循环将修改全局变量 $i 而不是创建局部变量。

    svn() {
    local i j k

    case $@ in
    ...
    esac
    }

导出决定子进程看到的内容。作用域决定函数是否修改全局变量。

关于Bash 变量范围泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30609973/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com