在Bash中,我应该使用声明而不是本地和导出吗?

时间:2019-06-17 08:30:19

标签: bash

我最近发现了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

我已经开始在各处使用它,并停止使用本地和导出。那么为什么localexport甚至存在?

2 个答案:

答案 0 :(得分:3)

由于历史原因,它们存在。 This manualdeclare是在bash第2版中引入的,local是在前面引入的。人们根据惯例和可读性使用localexportreadonly

当我看到local时,我想-“好!这必须是函数局部变量。我必须正在阅读一个函数。当我看到declare时,需要向上滚动直到看到函数声明,才能知道我是否在函数中,并查看变量是否为本地变量。

exportexport的内置POSIX,因此可以在任何地方使用,这一点很重要。但这是相似的。当我看到export时,我想-“好吧!该变量正在导出!当我看到declare -x时,需要使用declare选项刷新内存(很简单,-x听起来像export,但还有一点要记住)。我更喜欢写localexport。因为这是我的想法,所以-该变量是本地变量,该变量将导出。

当我仅使用localexport读取脚本而没有使用declare时,我知道这是一个简单的脚本。 declare -ideclare -n会使事情复杂化。

另外,typesetdeclare是完全同义词。因此,您也可能会问,declare何时可以使用typeset?可能已引入typeset,因此您可以使用ksh运行bash脚本而无需进行任何更改。与localreadonly关键字相同。与mapfilereadarray类似。惯例。对于文件,您可以使用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没有定义localdeclare,因此,如果要定位在最小sh shell上编写的脚本,则只有export可用(请注意,使用-f仍仅是Bash-ism而非POSIX)