bug-bash
[Top][All Lists]
Advanced

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

Re: declare a="$b" if $a previously set as array


From: konsolebox
Subject: Re: declare a="$b" if $a previously set as array
Date: Tue, 9 Dec 2014 10:51:51 +0800

On Sun, Dec 7, 2014 at 7:24 AM, Stephane Chazelas
<stephane.chazelas@gmail.com> wrote:
> $ b='($(uname>&2))' bash -c 'a=(); declare -r a=$b'
> Linux

I actually also don't like that form of implementation.  Even if declare
is a builtin and not a reserved word, it still has some special
treatments that's different from a simple command.  For example in a
simple command like echo, something like 'echo a=(1 2 3 4)' would cause
syntax error.  Word splitting and pathname expansion also doesn't happen
unless when assigning elements in an array.  If declare is able to
recognize assignments separated by spaces, I think it would have not
been difficult avoiding $b to be evaluated since it's really not meant
to be.  It clearly is a simple form of assignment.  Imo even if declare
is a builtin (which is actually a little special over a normal one), it
should have just emulated behavior of normal assignments and did nothing
more than it besides declaring the type (and optionally have some other
features not related to assignment).

(But I think those who used to recommend using declare as a general tool
for assigning values remotely over evil eval would love it since
it makes assignments like `declare -g "$var=$something"` possible
which naturally should have been illegal.)

Anyhow, this problem would only happen if a variable in a specific
scope (and only in that scope) has already been set previously as an
array and it doesn't always happen if you write your scripts well.

> It may be worth recommending people do a "unset var" before
> doing a "declare [-<option>] var"

I actually find it better to mention that on a simple assignment like
declare var=$something, var's type doesn't change if it has already been
declared previously as an array.

As for the unusual evaluation of $b, I believe that that implementation
should be changed and it's not enough to just warn users about it.

> (though in
> that case one may argue that they should use their own context
> and make sure they don't call other functions that modify
> variables in their parent context or be aware of what variables
> the functions they call may modify (recursively)).

And to add, if a script is meant to be sourced, it should make sure that
no unshared variable is still set after its execution ends.  If it has
to have variables that are meant to remain after it is sourced, then it
should make sure that those variables use their own namespaces like
having a prefix.  As a shared script it is natural to avoid conflicts
with variables of other scripts that would call you.  This is always
something you would always do whether declare is badly implemented or
not.

Shared functions otoh should be responsible of making sure that their
work variables are placed as local.  This is also a common practice.  As
for shared variables that would contain the results of the function,
those that are meant to contain array values should only contain array
values, and those non-array variables should always have non-array
values e.g. __A0 for array and __ for non-array.

Cheers,
konsolebox



reply via email to

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