'声明'在shell函数和环境变量范围

时间:2018-02-16 01:05:50

标签: bash

请考虑以下测试代码段(这些是文件的内容' declare_test'):

function do_foobar ()
{
  unset FOOBAR
  declare -- FOOBAR="default"
  FOOBAR="override"

  echo "At end of do_foobar: FOOBAR = \"$FOOBAR\""
}

从命令提示符运行do_foobar会导致:

$ source declare_test
$ do_foobar
At end of do_foobar: FOOBAR = "override"
$ echo "FOOBAR=\"$FOOBAR\""
FOOBAR=""

换句话说,在函数内部FOOBAR具有期望值,即"覆盖",但在函数FOOBAR 未设置之后立即。

如果我们更改了do_foobar并删除了'声明'行,然后结果是:

$ do_foobar
At end of do_foobar: FOOBAR = "override"
$ echo "FOOBAR=\"$FOOBAR\""
FOOBAR="override"

所以,现在FOOBAR没有被取消。请注意,已删除声明的功能是设置 FOOBAR。如果不是删除声明,我们删除行" FOOBAR ="覆盖",然后结果变为:

$ do_foobar
At end of do_foobar: FOOBAR = "default"
$ echo "FOOBAR=\"$FOOBAR\""
FOOBAR=""

因此,FOOBAR在功能之后仍未设置。

最后,如果你只删除未设置的FOOBAR,在调用do_foobar之前给FOOBAR一些值,那么结果就是FOOBAR没有改变! 因此,尽管有声明线,但未设置' 在函数之后有效,但声明本身和随后的其他赋值不再因声明而生效。

这对我来说是一个问题,因为我想从PROMPT_COMMAND调用一个shell函数,通过获取由' declare -p'生成的文件来恢复我的环境。 (存在一长串声明命令)。 显然bash不允许在函数内部使用声明,而它只允许直接设置变量。

这不是一个错误吗?它是在更高版本的bash中修复的吗? (我有4.3.48) 是否有解决此问题的方法,并不要求我更改我想要的文件(即该文件存在declare命令,我希望保持这种方式)。

1 个答案:

答案 0 :(得分:4)

declare限制函数内部变量的范围,类似于local所做的。如果要覆盖范围,请使用-g

#!/bin/bash

function do_foobar ()
{
    unset FOOBAR
    declare -g FOOBAR="default"
    FOOBAR="override"

    echo "At end of do_foobar: FOOBAR = \"$FOOBAR\""
}

$ source test.sh
$ do_foobar
At end of do_foobar: FOOBAR = "override"
$ echo "$FOOBAR"
override