[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
- Variables getting silently unset on redeclaration,
dtr <=