-a- 使 NAME 成为索引数组(如果支持)

-a- 使 NAME 成为索引数组(如果支持)

我的目标是了解“变量属性”的一般概念希望它能帮助我理解Bash 中声明了什么

什么是变量属性?为什么有人想要给变量赋予属性?为什么在使用变量时仅仅创建变量并在执行中扩展它们还不够“足够”?

答案1

通常,变量是存储值的地方。您为变量 ( ) 赋值var="some value",然后您可以通过变量扩展调用该值(写作"$var"相当于写作"some value")。

当您为变量赋值时,或者在 shell 访问变量的其他情况下,可以使变量执行一些特殊操作。变量的属性是 shell 存储在变量名称和值旁边的注释,它告诉 shell 应用此特殊行为。

一个例子

declare -i x告诉 shellx必须只包含整数值。通常,当您为变量赋值时,shell 会获取等号右侧展开后得到的字符串,并将其存储为变量的值。但是,如果变量具有整数属性,则 shell 会将该字符串解析为算术表达式,并存储对该表达式求值的结果。例如:

$ x=2+2; echo $x
2+2
$ declare -i x; x=2+2; echo $x
4
$ declare -i x; x=2+hello; echo $x
2
$ declare -i x; x=2+
bash: 2+: syntax error: operand expected (error token is "+")

(第三行x=2+hello设置x为 2,因为hello它是一个未定义的变量名,未设置的变量默认被默认解释为 0。)

更多示例

  • declare -l var声明var必须仅包含小写字母。当 shell 存储变量的值时,它会将所有大写字母转换为小写字母。
  • declare -u var进行另一个方向的转换。
  • declare -r var设为var只读,这也是赋值的一种特殊行为:它会导致每个后续赋值var失败。
  • declare -x var导致var被输出到环境中。对于此属性,当 bash 运行外部命令时,会发生特殊行为:外部命令看到的环境包含 shell 运行外部命令时 shell 导出的变量。

答案2

help declare

Options which set attributes:
    -a  to make NAMEs indexed arrays (if supported)
    -A  to make NAMEs associative arrays (if supported)
    -i  to make NAMEs have the `integer' attribute
    -l  to convert the value of each NAME to lower case on assignment
    -n  make NAME a reference to the variable named by its value
    -r  to make NAMEs readonly
    -t  to make NAMEs have the `trace' attribute
    -u  to convert the value of each NAME to upper case on assignment
    -x  to make NAMEs export

注意:declare也可用于函数。

这些属性中的每一个都有一种或多种用途:


-a- 使 NAME 成为索引数组(如果支持)

这并不是完全必要的,因为将参数设置为数组会自动将其声明为索引数组。使用它可以使您的代码更加明显和可读。


-A- 使名称关联数组(如果支持)

据我所知,这是完全必要的,因为尝试设置关联数组而不先声明它会导致索引数组。

$ assoc=([foo]=bar)
$ declare -p assoc
declare -a assoc=([0]="bar")
$ unset assoc
$ declare -A assoc
$ assoc=([foo]=bar)
$ declare -p assoc
declare -A assoc=([foo]="bar" )

-i- 使名称具有“整数”属性

如果您想确保您的参数可以,则很有用仅有的保存整数。这还允许您对赋值执行算术扩展。

$ declare -i a
$ a=foo
$ echo $a
0
$ a=1+1
$ echo $a
2

-l- 在分配时将每个 NAME 的值转换为小写

将确保您的参数值始终全部小写。这是一个非常酷的功能,我之前没有意识到并且将来可能会使用。它消除了复杂的参数扩展或使用单独的实用程序的需要,例如tr

$ declare -l foo=Bar
$ echo $foo
bar

-n- 使 NAME 成为对其值命名的变量的引用

就像间接引用一样。这可以消除eval许多脚本中的使用。

$ a=foo
$ declare -n b=a
$ echo $b
foo

-r- 使名称只读

这是一个很好的功能。它对于您想要设置一次并确保不更改的 shell/环境变量特别有用

$ declare -r foo=bar
$ echo $foo
bar
$ foo=baz
-bash: foo: readonly variable

-t- 使NAME具有“trace”属性

我对此不太确定。我认为它可能只适用于函数。


-u- 在赋值时将每个 NAME 的值转换为大写

相似-l但相反

$ declare -u foo=bAr
$ echo $foo
BAR

-x- 导出姓名

只是将变量导出到环境的另一种方法。


相关内容