[Top][All Lists]

[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  
-DSYS_BASHRC='/etc/bash/bashrc' -DSYS_BASH_LOGOUT='/etc/bash/bash_logout' 
-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

        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 

        #! /usr/bin/env bash

        set -eu
        set_var() {
                local name="$1" value="$2"
                # Fixing names
                # 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


reply via email to

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