描述变量的一般术语

描述变量的一般术语

使用 bash 4.3,手册和实际行为之间似乎存在差异:

unset string # just to be sure
declare string # $? is 0 afterwards
declare -p string # fails, 'string: not found'
printf %b "${string-unset}" "\n" # consequently, yields unset

内置声明/排版的手册部分没有声明需要在声明时进行赋值。相反,该declare [...] [...] name[=value]符号暗示这应该是合法的。

我缺少什么,它是“设置”变量的含义的定义吗?我是否误读了手册的“参数扩展”部分,它至少使用了术语“未设置”?或者这只是特定于版本的奇怪现象?

答案1

在 bash 版本高达 3.2 的情况下,顺序为:

 $ declare string; declare -p string

打印declare -- string="",这表明变量被设置为空字符串。

在版本 4.1、4.2 和 4.3 上,该变量没有设置为任何内容,这实际上会引发错误:

 $ declare string; declare -p string
 bash: declare: string: not found

在 bash 4.4 上解决:

 $ declare string; declare -p string
 declare -- string

这意味着字符串已被声明,但尚未为其分配任何值(甚至不是 null)。

答案2

事实上,对参数/变量含义的假设是未设置OP中的内容不精确。

man bash将变量定义为特殊类型的参数。因此,有关变量的信息有时位于仅涉及一般参数的部分中。

描述变量的一般术语

描述变量特征和状态的术语维基百科关于变量的文章

  1. 声明状态: 内存被保留,名称存在
  2. 初始化状态:除了1.之外,还赋值(声明后直接)
  3. 未初始化状态:值未定义,未设置初始值(仅发生了声明)
  4. 无效的value:某些编程语言返回的保留/特殊值,用于指示未初始化的变量

bash 手册中与变量相关的条目

  1. 设置状态:“如果参数已被赋值,则该参数已被设置。” [参数部分]
  2. 未设置状态,模棱两可,似乎适用于不存在/不再存在的变量以及根据一般术语处于“未初始化状态”的变量:“...bash 测试未设置的参数...”[参数扩展段]
  3. 空/空字符串- 空值:“如果参数已被赋值,则该参数被设置。空字符串是有效值。” [参数部分]
  4. 未设置内置- 命令“消灭”变量,例如unset string:“对于每个名称,删除相应的变量...”[SHELL BUILTIN COMMANDS 部分,'unset' 段落]
  5. 声明内置- 例如declare -p string:“-p 选项将显示每个名称的属性和值。” [SHELL BUILTIN COMMANDS 部分,'声明'/'排版' 段落]

重新陈述并回答原来的问题

这个问题应该更准确地表述为:“如何区分未初始化的 bash 变量和不存在的变量?

对此的答案是:

  1. 不要对此感到困惑unset内置从存在中删除一个变量并在其中删除一个变量未设置状态在 bash 术语中,它要么尚未声明,要么已声明为无值。

  2. declare对于已声明为无值的变量,内置命令在 bash 4.3 与 bash 4.4 中的行为确实不一致:

    $ # bash 4.3
    $ unset string; declare string; declare -p string; echo $?
    bash: declare: string: not found
    1
    $ # bash 4.4
    $ unset string; declare string; declare -p string; echo $?
    declare -- string
    0
    

    因此,这种测试正在使用的单个变量名称的方法并不通用,但似乎在最近的 bash 版本中有效。

  3. 不幸的是,参数扩展无助于区分不存在的变量和未初始化的变量,因为这两种情况都包含在相同的变量中。未设置状态:

    $ declare string; echo ${string-UNSET} # `string` exists, empty
    UNSET
    $ unset string; echo ${string-UNSET} # `string` does not exist
    UNSET
    
  4. 不幸的是,条件运算符也-v没有帮助[手册部分 CONDITIONAL EXPRESSIONS],它测试“shell 变量 VARNAME 是否已设置(已分配值)”,而不指示 VARNAME 是否存在:

    $ unset string; ! [ -v string ] && echo "unused"
    unused
    $ declare string; ! [ -v string ] && echo "unused"
    unused
    

相关话题

讨论重点介绍与参数/变量状态和值相关的术语混淆和 bash 细节:

  1. 如何检查变量是否存在...

  2. 如何测试 Bash 中是否定义了变量...

  3. 空字符串和“”是同一个字符串吗?

相关内容