`declare -p ` 是否检查变量(包括数组变量)是否已设置?

`declare -p ` 是否检查变量(包括数组变量)是否已设置?

是否declare -p检查变量(包括数组变量) 已设定?

为什么数组变量和非数组变量的行为不同?

对于数组变量:

$ unset ar
$ declare -a ar=()
$ declare -p ar
declare -a ar='()'
$ echo ${ar[@]-This is a new value}
This is a new value

$ unset ar
$ declare -a ar
$ declare -p ar
bash: declare: ar: not found
$ echo ${ar[@]-This is a new value}
This is a new value

对于非数组变量:

$ unset var
$ declare -i var
$ declare -p var
bash: declare: var: not found
$ echo ${var-This is a new value}
This is a new value

谢谢。


我正在运行 Bash 4.3.48。

https://unix.stackexchange.com/a/381491/674,听说在4.4中,运行unset ar和后declare -a ar,运行的输出declare -p vardeclare -a ar

我想知道是否declare -p在 bash 4.4 中。数组的处理方式与其他类型不同。在4.4中,运行unset var和后declare -i var,运行 的输出是什么declare -p var。是输出error such as bash: declare: var: not found还是declare -i var

答案1

如果给定数组一个列表,所有 bash 版本都会正确处理数组()
或者给数组元素一个值(甚至为空)。
此代码(使用排版使其在 ksh 中运行):

unset ar; typeset -a ar=()
printf '%-20s%s ' "$(typeset -p ar)" '--'

unset ar; typeset -a ar; ar[3]=""
printf '%-30s%s ' "$(typeset -p ar)" '@@'

unset ar; typeset -a ar; ar[3]="val"
printf '%-31s ' "$(typeset -p ar)"

将打印此结果:

zsh/sh          : typeset -a ar=(  )  -- typeset -a ar=( '' '' '' '' ) @@ typeset -a ar=( '' '' '' val )
b203sh          : declare -a ar='()'  -- declare -a ar='([3]="")'      @@ declare -a ar='([3]="val")'
b204sh          : declare -a ar='()'  -- declare -a ar='([3]="")'      @@ declare -a ar='([3]="val")'
b205sh          : declare -a ar='()'  -- declare -a ar='([3]="")'      @@ declare -a ar='([3]="val")'
b30sh           : declare -a ar='()'  -- declare -a ar='([3]="")'      @@ declare -a ar='([3]="val")'
b32sh           : declare -a ar='()'  -- declare -a ar='([3]="")'      @@ declare -a ar='([3]="val")'
b41sh           : declare -a ar='()'  -- declare -a ar='([3]="")'      @@ declare -a ar='([3]="val")'
b42sh           : declare -a ar='()'  -- declare -a ar='([3]="")'      @@ declare -a ar='([3]="val")'
b43sh           : declare -a ar='()'  -- declare -a ar='([3]="")'      @@ declare -a ar='([3]="val")'
b44sh           : declare -a ar=()    -- declare -a ar=([3]="")        @@ declare -a ar=([3]="val")
ksh93           : typeset -a ar       -- typeset -a ar=([3]='')        @@ typeset -a ar=([3]=val)
attsh           : typeset -a ar       -- typeset -a ar=([3]='')        @@ typeset -a ar=([3]=val)
zsh/ksh         : typeset -a ar=(  )  -- typeset -a ar=( '' '' '' '' ) @@ typeset -a ar=( '' '' '' val )
zsh             : typeset -a ar=(  )  -- typeset -a ar=( '' '' '' )    @@ typeset -a ar=( '' '' val )

正如您所看到的,所有 shell(有一些差异)都运行代码并提供相同的结果。


此外,所有 shell 都可以使用此代码:

unset ar; typeset -i ar              ; printf '%-17s%s ' "$(typeset -p ar)" '=='
unset ar; typeset -a ar              ; printf '%-19s%s ' "$(typeset -p ar)" '++'

并打印:

zsh/sh          : typeset -i ar=0  == typeset -a ar=(  ) ++
b203sh          : declare -i ar="" == declare -a ar='()' ++
b204sh          : declare -i ar="" == declare -a ar='()' ++
b205sh          : declare -i ar="" == declare -a ar='()' ++
b30sh           : declare -i ar="" == declare -a ar='()' ++
b32sh           : declare -i ar="" == declare -a ar='()' ++
b44sh           : declare -i ar    == declare -a ar      ++
ksh93           : typeset -i ar    == typeset -a ar      ++
attsh           : typeset -i ar    == typeset -a ar      ++
zsh/ksh         : typeset -i ar=0  == typeset -a ar=(  ) ++
zsh             : typeset -i ar=0  == typeset -a ar=(  ) ++

粗略的补丁位于 bash 系列 4 中。4.1 和 4.2 都适用于数组:

b41sh           : declare -a ar='()' ++
b42sh           : declare -a ar='()' ++

但不适用于简单变量。 bash 4.3 在这两个测试中都失败了:

b43sh           : script: line 3: typeset: ar: not found ==
                  script: line 4: typeset: ar: not found ++

因此,对于此测试,请移出 Bash 4.3 --。

相关内容