[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Issues modifying a local variable inside of a subfunction
From: |
Lawrence Velázquez |
Subject: |
Re: Issues modifying a local variable inside of a subfunction |
Date: |
Mon, 11 Oct 2021 23:18:43 -0400 |
User-agent: |
Cyrus-JMAP/3.5.0-alpha0-1345-g8441cd7852-fm-20211006.001-g8441cd78 |
On Mon, Oct 11, 2021, at 10:08 PM, Hunter Wittenborn wrote:
> I'm currently having some issues modifying shell variable that have
> been declared with 'local' via subfunctions in a given function.
>
> The following gives what my actual script is trying to do:
>
> """
> #!/usr/bin/env bash
> test1() {
> variable="${1}"
> declare -g "${variable}=1"
> }
>
> test2() {
> local number=0
> test1 number
> echo "${number}"
> }
>
> test2
> """
>
> Why is this outputting "0" instead of "1"? After reading over the Bash
> man pages I was thinking 'declare -g' might be assigning to a variable
> reference outside of that made by my 'local' command
That's right. The 'declare -g' command operates on the global
scope, not the immediately enclosing scope (unless that *is* the
global scope).
% cat /tmp/foo1.bash; echo
test1() {
declare -g "$1"=1
}
test2() {
local number=0
test1 number
printf 'test2: %s\n' "$number"
}
number=2
test2
printf 'global: %s\n' "$number"
% bash /tmp/foo1.bash
test2: 0
global: 1
> but at that point I can't figure out how I can modify the value
> of 'number' while inside a subfunction of the 'test2()' function.
You're conflating a couple of things here. You can easily modify
test2's 'number' from within 'test1'.
% cat /tmp/foo2.bash; echo
test1() {
number=1
}
test2() {
local number=0
test1
printf 'test2: %s\n' "$number"
}
number=2
test2
printf 'global: %s\n' "$number"
% bash /tmp/foo2.bash
test2: 1
global: 2
However, since you're using 'declare' to do indirect assignments,
you can modify local variables and global variables but nothing in
between.
> Is this a bug, or is it just behaving as expected from how I described
> above? If the latter, is there any way to accomplish what I'm wanting
> to do?
Ideally you would avoid doing indirect assignments. Without context,
it's hard to make a holistic suggestion. You can avoid the scoping
issue by using a technique that doesn't involve 'declare'. For
example:
% cat /tmp/foo3.bash; echo
test1() {
printf -v "$1" '%s' 1
}
test2() {
local number=0
test1 number
printf 'test2: %s\n' "$number"
}
number=2
test2
printf 'global: %s\n' "$number"
% bash /tmp/foo3.bash
test2: 1
global: 2
There are many such techniques, and each one comes with its own
baggage. Have fun!
https://mywiki.wooledge.org/BashFAQ/006#Assigning_indirect.2Freference_variables
--
vq