[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Expansions based on variable existence (e.g. ${var+exists}) yield in
From: |
Chet Ramey |
Subject: |
Re: Expansions based on variable existence (e.g. ${var+exists}) yield inconsistent results. |
Date: |
Mon, 20 Apr 2020 15:38:02 -0400 |
User-agent: |
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 |
On 4/20/20 11:55 AM, andrej--- via Bug reports for the GNU Bourne Again
SHell wrote:
> Bash Version: 5.0
> Patch Level: 16
> Release Status: release
>
> Description:
> Variable existence testing doesn't match variables that are (only) declared.
> Unless the declared variables are redeclared as arrays. Other variable
> existence tests yield surprising results as well. (This is all about
> existence
> tests, i.e., ones without the extra ':' that tests for emptiness.)
>
> In particular, Example 4 below exposes a situation in which a variable
> doesn't
> seem to be set, yet cannot be set. Example 5 below shows that empty arrays
> are treated differently in terms of variable existence. Also, redeclaration
> of
> a variable as an array seems to have an "assignment effect" on it (in the
> sense of making it detectable by existence tests). Redeclaration as an
> integer
> doesn't have this effect.
>
> Repeat-By:
> Example 1:
> declare var # The same problem occurs with -i, -a and -A.
> echo "${!var@}" # empty [unexpected]
> echo "${var+exists}" # empty [unexpected]
> echo "${var-nonexistent}" # nonexistent [unexpected]
var is unset; you have not assigned a value.
>
> Example 2:
> declare var
> declare -A var
This is a bug; var should remain unset since it has no value. It happens as
part of the process converting the variable to an associative array.
> echo "${!var@}" # var [expected] << Difference from
> Experiment 1
> echo "${var+exists}" # empty [unexpected]
> echo "${var[@]+exists}" # empty [somewhat unexpected]
> echo "${var-nonexistent}" # nonexistent [unexpected]
> echo "${var[@]-nonexistent}" # nonexistent [somewhat unexpected]
>
> Example 3:
> declare var=
> echo "${!var@}" # var [expected]
> echo "${var+exists}" # exists [expected]
> echo "${var-nonexistent}" # empty [expected]
var is set with an empty value.
>
> Example 4:
> declare -r var
> echo "${!var@}" # empty [unexpected]
> echo "${var+exists}" # empty [unexpected]
> echo "${var-nonexistent}" # nonexistent [unexpected]
> var= # Error! [inconsistent]
var is unset until you attempt to assign it a value. It exists only as an
unset variable with attributes.
>
> Example 5:
> var=()
> echo "${!var@}" # var [expected]
> echo "${var+exists}" # empty [unexpected]
> echo "${var[@]+exists}" # empty [somewhat unexpected]
An empty array is set (or, more precisely, it is not unset). It's like
assigning a null string to a variable.
> echo "${var-nonexistent}" # nonexistent [unexpected]
This is the same as var[0].
> echo "${var[@]-nonexistent}" # nonexistent [somewhat unexpected]
There aren't any values there. I suppose it could expand to the empty
string, but it doesn't.
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU chet@case.edu http://tiswww.cwru.edu/~chet/