Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: x86_64-pc-linux-gnu-gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I./include -I. -I./include -I./lib -DDEFAULT_PATH_VALUE='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' -DSTANDARD_UTILS_PATH='/bin:/usr/bin:/sbin:/usr/sbin' -DSYS_BASHRC='/etc/bash/bashrc' -DSYS_BASH_LOGOUT='/etc/bash/bash_logout' -DNON_INTERACTIVE_LOGIN_SHELLS -DSSH_SOURCE_BASHRC -march=sandybridge -O2 -pipe -fomit-frame-pointer -Wno-parentheses -Wno-format-security uname output: Linux home 4.9.75 #3 SMP PREEMPT Mon Jan 29 16:20:22 MSK 2018 x86_64 Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz GenuineIntel GNU/Linux Machine Type: x86_64-pc-linux-gnu
Bash Version: 4.4 Patch Level: 12 Release Status: release Description: Variables mistakenly declared as local and then set as global happen to be unset for the ânounsetâ option and known to âdeclare -pâ at the same time. Moreover, whatever value was assigned to them is lost. Re-declaration doesnât cause an error, and such variables may cause silent failure, because the error can only be caught on the first use and only in two cases: - nounset option is on; - a test on variable existence [ -v is called and errexit is on. The unset variable isnât unset for declare, which is confusing. Expected behaviour: Variables should either change their type to global and maintain the value assigned to them, or trigger SIGERR on re-declaration, (and not when theyâre caught much later by âerrexitâ or ânounsetâ). Repeat-By: #! /usr/bin/env bash set -eu set_var() { local name="$1" value="$2" # Fixing names name=${name//-/_} name=${name//\//_} # Here should be some work # to retrieve data⦠declare -g $name="$value" # my_poor_var is already unset here return 0 } func() { # mistakenly left among local variables local my_poor_var set_var my-poor/var 2 # (1) [ -v my_poor_var ] # quits on SIGERR # (2) echo "$my_poor_var" # line 18: my_poor_var: unbound variable # (3) declare -p my_poor_var # Reports, that it exists(!), but has no value. # Calling declare -p doesnât make the program quit, # unlike with really unset variables return 0 } func