help-bash
[Top][All Lists]
Advanced

[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



reply via email to

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