我最近发现了declare
Bash内置函数,它声明了具有局部作用域的变量,还可以用于导出变量甚至设置类型。
# 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
我已经开始在各处使用它,并停止使用本地和导出。那么为什么local
和export
甚至存在?
答案 0 :(得分:3)
由于历史原因,它们存在。 This manual说declare
是在bash
第2版中引入的,local
是在前面引入的。人们根据惯例和可读性使用local
,export
和readonly
。
当我看到local
时,我想-“好!这必须是函数局部变量。我必须正在阅读一个函数。当我看到declare
时,需要向上滚动直到看到函数声明,才能知道我是否在函数中,并查看变量是否为本地变量。
export
是export
的内置POSIX,因此可以在任何地方使用,这一点很重要。但这是相似的。当我看到export
时,我想-“好吧!该变量正在导出!当我看到declare -x
时,需要使用declare
选项刷新内存(很简单,-x
听起来像export
,但还有一点要记住)。我更喜欢写local
和export
。因为这是我的想法,所以-该变量是本地变量,该变量将导出。
当我仅使用local
和export
读取脚本而没有使用declare
时,我知道这是一个简单的脚本。 declare -i
或declare -n
会使事情复杂化。
另外,typeset
和declare
是完全同义词。因此,您也可能会问,declare
何时可以使用typeset
?可能已引入typeset
,因此您可以使用ksh
运行bash
脚本而无需进行任何更改。与local
和readonly
关键字相同。与mapfile
和readarray
类似。惯例。对于文件,您可以使用mapfile
,但是对于此处的字符串,有时我也可以使用readarray
,因为我正在将一些数据读取到数组中,而不是映射文件。
我相信local
关键字比declare
更可移植。您可以阅读前。 this unix.stackexchange thread了解更多信息。
答案 1 :(得分:1)
在大多数情况下,是的!但是请记住,在大多数情况下,使用declare
且其标志很少会使外壳程序将其解释为表达式 rather 而不是简单的赋值字符串。假设您想定义一个变量,以仅保留具有-i
属性的整数值
declare -i x; x=2+2; echo $x
4
export x; x=2+2; echo $x
2+2
shell强制将赋值视为整数表达式,而不是普通变量赋值。 export
/ local
命令没有定义要应用于分配的特殊处理。
还比local
提供的属性更早地将内置export
/ bash
添加到declare
中。 POSIX没有定义local
或declare
,因此,如果要定位在最小sh
shell上编写的脚本,则只有export
可用(请注意,使用-f
仍仅是Bash-ism而非POSIX)