bug-bash
[Top][All Lists]
Advanced

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

Stumped on a question of scoping and unset.


From: Steven W. Orr
Subject: Stumped on a question of scoping and unset.
Date: Wed, 25 May 2011 17:15:28 -0400
User-agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.17) Gecko/20110414 Thunderbird/3.1.10

I picked up a cool routine called upvars from this location:

http://fvue.nl/wiki/Bash:_Passing_variables_by_reference

I've been using it a lot, but I just ran into a debugging nightmare that I do not understand. I'm using the upvars function described in the link above. In addition, I wrote (what I thought was pretty clever) a function called glob_array:

glob_array()
{
    typeset arrayname
    typeset pattern
    typeset -a aval
    typeset -i nullglob_status=0
    typeset -r nullglob_reset=su        # Set Unset
    typeset -i nn=0

    (( $# & 1 )) && die 'ERROR: glob_array takes an even number of args'
    shopt -p nullglob > /dev/null
    nullglob_status=$?
    shopt -s nullglob

    while (( $# ))
    do
        arrayname=$1
        pattern="$2"
        aval=( $pattern )
        nn=${#aval[@]}
        # This should never fail as long as $nn matches passing all of aval.
        # Check anyways for extra credit.
        upvars -a$nn $arrayname "${aval[@]}" || die "ERROR:upvars failed."
        shift 2
    done
    shopt -${nullglob_reset:$nullglob_status:1} nullglob
}

Note that glob_array called upvars. Here's where the trouble happens:

#! /bin/bash

. upvar || die 'Failed to load upvar'
. globarray || die 'Failed to load globarray'

mk_versions()
{
    typeset -a bebldsrc

    glob_array bebldsrc '*.sh'
    echo "bebldsrc:${bebldsrc[@]}"
}

typeset -a bebldsrc

glob_array bebldsrc '*.txt'
echo "main:bebldsrc:${bebldsrc[@]}"
mk_versions
echo "main2:bebldsrc:${bebldsrc[@]}"

When I run this program, the call to glob_array in mk_versions, stomps on the bebldsrc array at the global scope instead of just setting the local copy in mk_versions. Here's the output:

711 > ./foo.sh
main:bebldsrc:be-ESX-HOWTO-stage.txt be-FW-HOWTO-stage.txt be-HOWTO-stage.txt
bebldsrc:build_netiscsi_pkg.sh copy_hp_srpms.sh foo.sh sni-28.sh stage-net-iscsi.sh stage_be_fw.sh unpack-net-iscsi.sh update-be-tarballs.sh update-net-iscsi-pkg.sh main2:bebldsrc:build_netiscsi_pkg.sh copy_hp_srpms.sh foo.sh sni-28.sh stage-net-iscsi.sh stage_be_fw.sh unpack-net-iscsi.sh update-be-tarballs.sh update-net-iscsi-pkg.sh

The problem seems to be in the definition of upvars. Am I not allowed to use glob_array in the same function as the variable that the variable is declared in?

The relevant code in upvars is (probably) this:
       # Error checking
       [[ ${1#-a} ]] || { echo "bash: ${FUNCNAME[0]}: \`$1': missing"\
                    "number specifier" 1>&2; return 1; }
       printf %d "${1#-a}" &> /dev/null || { echo "bash:"\
                    "${FUNCNAME[0]}: \`$1': invalid number specifier" 1>&2
                    return 1; }
       # Assign array of -aN elements
       [[ "$2" ]] && unset -v "$2" && eval $2=\(\"\${@:3:${1#-a}}\"\) &&
                shift $((${1#-a} + 2)) || { echo "bash: ${FUNCNAME[0]}:"\
                    "\`$1${2+ }$2': missing argument(s)" 1>&2; return 1; }

* Why is it needed to use the unset?
* What does unset -v do extra for me?
* What bad things could happen if I don't do the unset?

Anyone have any ideas? :-(

--
Time flies like the wind. Fruit flies like a banana. Stranger things have  .0.
happened but none stranger than this. Does your driver's license say Organ ..0
Donor?Black holes are where God divided by zero. Listen to me! We are all- 000
individuals! What if this weren't a hypothetical question?
steveo at syslang.net



reply via email to

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