考虑以下测试片段(这些是文件“declare_test”的内容):
function do_foobar ()
{
unset FOOBAR
declare -- FOOBAR="default"
FOOBAR="override"
echo "At end of do_foobar: FOOBAR = \"$FOOBAR\""
}
Run Code Online (Sandbox Code Playgroud)
从命令提示符运行 do_foobar 会产生:
$ source declare_test
$ do_foobar
At end of do_foobar: FOOBAR = "override"
$ echo "FOOBAR=\"$FOOBAR\""
FOOBAR=""
Run Code Online (Sandbox Code Playgroud)
换句话说,函数 FOOBAR 内部具有预期值,即“覆盖”,但在函数 FOOBAR 立即被取消设置之后。
如果我们更改 do_foobar 并删除“declare”行,则结果是:
$ do_foobar
At end of do_foobar: FOOBAR = "override"
$ echo "FOOBAR=\"$FOOBAR\""
FOOBAR="override"
Run Code Online (Sandbox Code Playgroud)
所以,现在 FOOBAR 没有被重置。请注意,删除的声明的功能是设置FOOBAR。如果我们不删除声明而是删除“FOOBAR=”override”行,则结果将变为:
$ do_foobar
At end of do_foobar: FOOBAR = "default"
$ echo "FOOBAR=\"$FOOBAR\""
FOOBAR=""
Run Code Online (Sandbox Code Playgroud)
因此,函数执行后 FOOBAR 仍未设置。
最后,如果你只删除未设置的FOOBAR,在调用do_foobar之前给FOOBAR一些值,那么结果是FOOBAR没有改变!因此,尽管有声明行,“取消设置”确实在函数之后有效,但声明本身和后续其他赋值不再因为声明而起作用。
这对我来说是一个问题,因为我想从 PROMPT_COMMAND 调用 shell 函数,该函数通过获取由“declare -p”(存在一长串声明命令)生成的文件来恢复我的环境。显然 bash 不允许在函数内使用声明,但它允许直接设置变量。
这不是一个bug吗?bash 的更高版本中修复了吗?(我有 4.3.48)这个问题是否有解决方法,不需要我更改我想要获取的文件(即该文件存在声明命令,我想保持这种状态)。
declare限制函数内变量的范围,类似于local。如果您想覆盖范围,请使用-g.
#!/bin/bash
function do_foobar ()
{
unset FOOBAR
declare -g FOOBAR="default"
FOOBAR="override"
echo "At end of do_foobar: FOOBAR = \"$FOOBAR\""
}
Run Code Online (Sandbox Code Playgroud)
。
$ source test.sh
$ do_foobar
At end of do_foobar: FOOBAR = "override"
$ echo "$FOOBAR"
override
Run Code Online (Sandbox Code Playgroud)