bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Variables getting silently unset on redeclaration


From: dtr
Subject: Variables getting silently unset on redeclaration
Date: Fri, 16 Mar 2018 05:30:15 +0300

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]