Path: csiph.com!goblin1!goblin.stu.neva.ru!usenet.stanford.edu!not-for-mail From: Greg Wooledge Newsgroups: gnu.bash.bug Subject: Re: Incorrect / Inconsistent behavior with nameref assignments in functions Date: Fri, 28 Aug 2020 11:28:46 -0400 Lines: 50 Approved: bug-bash@gnu.org Message-ID: References: <20200828152846.GI931@eeg.ccf.org> NNTP-Posting-Host: lists.gnu.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: usenet.stanford.edu 1598628532 6405 209.51.188.17 (28 Aug 2020 15:28:52 GMT) X-Complaints-To: action@cs.stanford.edu To: bug-bash@gnu.org Envelope-to: bug-bash@gnu.org Mail-Followup-To: bug-bash@gnu.org Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Received-SPF: none client-ip=139.137.100.1; envelope-from=wooledg@eeg.ccf.org; helo=mail.eeg.ccf.org X-detected-operating-system: by eggs.gnu.org: First seen = 2020/08/28 11:22:53 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, KHOP_HELO_FCRDNS=0.4, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: bug-bash@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Bug reports for the GNU Bourne Again SHell List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Mailman-Original-Message-ID: <20200828152846.GI931@eeg.ccf.org> X-Mailman-Original-References: Xref: csiph.com gnu.bash.bug:16829 On Fri, Aug 28, 2020 at 10:56:34AM +0200, Binarus wrote: > #!/bin/bash > > function Dummy() { > > local -n namerefArray="$1" > local -a -i myArray=("${namerefArray[@]}") > > local -p > } > > declare -a -i myArray=('1' '2' '3') You've got a local variable with the same name as the global variable that you're attempting to pass by reference. This will not work. Namerefs (declare -n) in bash are *not* like uplevel commands in Tcl. They cause the referenced variable name to be evaluated just like any other variable would be, starting at the current function scope, then going up to the caller, and so on. If you want to use namerefs in a function in bash, you MUST go out of your way to minimize the chances of a collision between the caller's variable refererance and ANY local variable of the function. Not just the nameref itself, but any other incidental variables used in the function. (As you aptly demonstrated here.) So, you can't write functions like this: func1() { declare -n ref="$1" local i ... } Instead, you need crazy things like this: func1() { declare -n _func1_ref="$1" local _func1_i ... } And then you just have to pray that the caller respects you enough not to use variables named with _func1_ prefixes. There is no 100% bulletproof solution to this issue. See also .