我最近发现了declareBash 内置函数,它声明具有局部作用域的变量,也可用于导出变量甚至设置类型。
# bar an baz have local scope
foo()
{
declare bar
local baz
}
# bing and bong are both exported
declare -x bing
export bong
# i is an integer, j is read-only integer
declare -i i=0
declare -ri j=10
Run Code Online (Sandbox Code Playgroud)
我已经开始在任何地方使用它并停止使用本地和导出。那么,为什么local和export甚至存在吗?
他们的存在是因为历史。本手册说declare是在bash版本2local中引入的,较早引入。人们使用local,export并且readonly按照惯例和可读性。
当我看到local我想 - '哦!这必须是函数局部变量。我一定是在读一个函数。'。当我看到declare我需要向上滚动直到看到函数声明时,才能知道我是否在函数中并查看变量是否是局部变量。
使用export,export是 POSIX 内置函数,因此它可以在任何地方使用,这很重要。但它是相似的。当我看到export我想 - '哦!这个变量正在被导出!'。当我看到declare -x我需要用declare选项来刷新我的记忆时(嗯,这很容易,-x听起来像export,但它仍然是要记住的另一件事)。我更喜欢写作local和export. 因为这是我的想法 - 这个变量是本地的,那个变量是导出的。
当我仅使用localand阅读脚本export而不使用 时declare,我知道这是一个简单的脚本。declare -i或者declare -n可以使事情复杂化。
此外,typeset和declare是完全同义词。所以,你也可以问,为什么declare,什么时候可以typeset?可能typeset已引入,因此您无需任何更改即可运行ksh脚本bash。与local和readonly关键字相同。与mapfile和类似readarray。习俗。对于文件,您可以使用mapfile,但有时会使用 here 字符串readarray,因为我正在将一些数据读入数组,而不是映射文件。
我相信local关键字比(有点?)更便携declare。你可以读ex。这个 unix.stackexchange 线程了解更多信息。
大多数情况下是的!但请记住,declare在大多数情况下使用很少的标志会导致 shell 将它们解释为表达式,而不仅仅是简单的赋值字符串。假设您想定义一个变量来保存具有-i属性的纯整数值
declare -i x; x=2+2; echo $x
4
export x; x=2+2; echo $x
2+2
Run Code Online (Sandbox Code Playgroud)
shell 强制将赋值视为整数表达式而不是普通变量赋值。export/命令local没有定义要应用于分配的特殊处理。
此外,内置local/ 的export添加时间bash比提供的属性要早得多declare。POSIX 没有定义localor declare,因此如果您要以最小shshell 编写的目标脚本, onlyexport可用(请注意,导出函数-f仍然只是 Bash-ism 而不是 POSIX )