Path: csiph.com!goblin2!goblin1!goblin.stu.neva.ru!usenet.stanford.edu!not-for-mail From: andrej@podzimek.org Newsgroups: gnu.bash.bug Subject: Expansions based on variable existence (e.g. ${var+exists}) yield inconsistent results. Date: Mon, 20 Apr 2020 17:55:46 +0200 Lines: 67 Approved: bug-bash@gnu.org Message-ID: References: NNTP-Posting-Host: lists.gnu.org X-Trace: usenet.stanford.edu 1587405460 9496 209.51.188.17 (20 Apr 2020 17:57:40 GMT) X-Complaints-To: action@cs.stanford.edu To: bug-bash@gnu.org Envelope-to: bug-bash@gnu.org Received-SPF: pass client-ip=2a02:168:5cd0::; envelope-from=andrej@podzimek.org; helo=charon.podzimek.org X-detected-operating-system: by eggs1p.gnu.org: Error: [-] PROGRAM ABORT : Malformed IPv6 address (bad octet value). Location : parse_addr6(), p0f-client.c:67 X-Received-From: 2a02:168:5cd0:: X-Mailman-Approved-At: Mon, 20 Apr 2020 13:57:38 -0400 X-BeenThere: bug-bash@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Bug reports for the GNU Bourne Again SHell List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Mailman-Original-Message-ID: Xref: csiph.com gnu.bash.bug:16193 Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -DDEFAULT_PATH_VALUE='/usr/local/sbin:/usr/local/bin:/usr/bin' -DSTANDARD_UTILS_PATH='/usr/bin' -DSYS_BASHRC='/etc/bash.bashrc' -DSYS_BASH_LOGOUT='/etc/bash.bash_logout' -DNON_INTERACTIVE_LOGIN_SHELLS -Wno-parentheses -Wno-format-security uname output: Linux charon 5.6.4-arch1-1-user-regd #1 SMP PREEMPT Fri, 17 Apr 2020 12:06:27 +0000 x86_64 GNU/Linux Machine Type: x86_64-pc-linux-gnu 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] Example 2: declare var declare -A var 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] Example 4: declare -r var echo "${!var@}" # empty [unexpected] echo "${var+exists}" # empty [unexpected] echo "${var-nonexistent}" # nonexistent [unexpected] var= # Error! [inconsistent] Example 5: var=() echo "${!var@}" # var [expected] echo "${var+exists}" # empty [unexpected] echo "${var[@]+exists}" # empty [somewhat unexpected] echo "${var-nonexistent}" # nonexistent [unexpected] echo "${var[@]-nonexistent}" # nonexistent [somewhat unexpected] var=(blah) echo "${var+exists}" # exists [expected] echo "${var[@]+exists}" # exists [expected] echo "${var-nonexistent}" # blah [expected] echo "${var[@]-nonexistent}" # blah [expected]