[-- Attachment #1: Type: text/plain, Size: 335 bytes --] Hello, I'm trying to assign the content of an array to another which name is contained in a variable What I tried: varname=newarray typeset -a array=(1 2 3) typeset -a $varname=($array) but I get an zsh: bad pattern: newarray=(1 are there other methods to do indirect assignment that allow me to do this? thanks Pier Paolo Grassi
On 4/16/20, Pier Paolo Grassi <pierpaolog@gmail.com> wrote:
> Hello, I'm trying to assign the content of an array to another which name
> is contained in a variable
> What I tried:
>
> varname=newarray
> typeset -a array=(1 2 3)
> typeset -a $varname=($array)
>
> but I get an
> zsh: bad pattern: newarray=(1
>
> are there other methods to do indirect assignment that allow me to do this?
: ${(PA)varname::=$array}
(leave out the A for scalar assignment, and use AA for assoc arrays).
--
Mikael Magnusson
[-- Attachment #1: Type: text/plain, Size: 1038 bytes --] Thanks! I was afraid I had to resort to eval. By the way, I was trying to create an helper function like this: debugvar(){ typeset -g $1 typeset +m $1 typeset $1 } but I found out from the manual that -g "it has no effect when listing existing parameters" is there a way to use typeset from functions to print out the definition of global variables? thanks again Pier Paolo Grassi Il giorno gio 16 apr 2020 alle ore 01:13 Mikael Magnusson <mikachu@gmail.com> ha scritto: > On 4/16/20, Pier Paolo Grassi <pierpaolog@gmail.com> wrote: > > Hello, I'm trying to assign the content of an array to another which name > > is contained in a variable > > What I tried: > > > > varname=newarray > > typeset -a array=(1 2 3) > > typeset -a $varname=($array) > > > > but I get an > > zsh: bad pattern: newarray=(1 > > > > are there other methods to do indirect assignment that allow me to do > this? > > : ${(PA)varname::=$array} > (leave out the A for scalar assignment, and use AA for assoc arrays). > > -- > Mikael Magnusson >
On Wed, Apr 15, 2020 at 4:43 PM Pier Paolo Grassi <pierpaolog@gmail.com> wrote:
>
> is there a way to use typeset from functions to print out the definition of
> global variables?
typeset -p should do it, as long as a parameter of the same name has
not already been declared local.
[-- Attachment #1: Type: text/plain, Size: 813 bytes --] I see, for debug purposes it works indeed, but I don't have the output of typeset +m that would have printed array for array parameters. I wanted to capture that output to test for variables of type array. Is there a way to test if a variable is of type array? regards Pier Paolo Grassi linkedin: https://www.linkedin.com/in/pier-paolo-grassi-19300217 founder: https://www.meetup.com/it-IT/Machine-Learning-TO Il giorno gio 16 apr 2020 alle ore 01:55 Bart Schaefer < schaefer@brasslantern.com> ha scritto: > On Wed, Apr 15, 2020 at 4:43 PM Pier Paolo Grassi <pierpaolog@gmail.com> > wrote: > > > > is there a way to use typeset from functions to print out the definition > of > > global variables? > > typeset -p should do it, as long as a parameter of the same name has > not already been declared local. >
On Wed, Apr 15, 2020 at 5:06 PM Pier Paolo Grassi <pierpaolog@gmail.com> wrote:
>
> Is there a way to test if a variable is of type array?
var=module_path
print -r ${(tP)var} $var
[-- Attachment #1: Type: text/plain, Size: 451 bytes --] cool, thanks! Pier Paolo Grassi linkedin: https://www.linkedin.com/in/pier-paolo-grassi-19300217 founder: https://www.meetup.com/it-IT/Machine-Learning-TO Il giorno gio 16 apr 2020 alle ore 02:12 Bart Schaefer < schaefer@brasslantern.com> ha scritto: > On Wed, Apr 15, 2020 at 5:06 PM Pier Paolo Grassi <pierpaolog@gmail.com> > wrote: > > > > Is there a way to test if a variable is of type array? > > var=module_path > print -r ${(tP)var} $var >
[-- Attachment #1: Type: text/plain, Size: 401 bytes --] On Thu, 16 Apr 2020 at 01:14, Mikael Magnusson <mikachu@gmail.com> wrote: > : ${(PA)varname::=$array} > (leave out the A for scalar assignment, and use AA for assoc arrays). > I would do: : ${(PA)varname::="$array[@]"} to not lose empty elements. -- Sebastian Gniazdowski News: https://twitter.com/ZdharmaI IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zinit Blog: http://zdharma.org
2020-04-16 01:42:29 +0200, Pier Paolo Grassi: > Il giorno gio 16 apr 2020 alle ore 01:13 Mikael Magnusson <mikachu@gmail.com> > ha scritto: [...] > > : ${(PA)varname::=$array} > > (leave out the A for scalar assignment, and use AA for assoc arrays). [...] > Thanks! I was afraid I had to resort to eval. [...] What's wrong with "eval"? Note that many of those alternatives to "eval" are just other evals in disguise or are as dangerous (but giving the wrong impression that they're not). : ${(PA)varname::=$array} is a command injection vulnerability if the content of $varname is not sanitized. $ varname='x[$(uname>&2)]' $ : ${(PA)varname::=$array} Linux zsh: bad math expression: empty string So is: eval $varname'=("$array[@]")' but at least it's more obvious that it is. In any case, I'd expect the contents of $varname to be known and trusted in this case, while that of $array could be anything. Note that that "$array[@]" (instead of $array) is needed to preserve empty elements. -- Stephane
[-- Attachment #1: Type: text/plain, Size: 1507 bytes --] thanks Stephane, it is indeed a good habit to sanitize the varname whichever method is utilized. From your explanation I admit the eval solution would have been equally valid regards Pier Paolo Grassi linkedin: https://www.linkedin.com/in/pier-paolo-grassi-19300217 founder: https://www.meetup.com/it-IT/Machine-Learning-TO Il giorno gio 16 apr 2020 alle ore 18:30 Stephane Chazelas < stephane@chazelas.org> ha scritto: > 2020-04-16 01:42:29 +0200, Pier Paolo Grassi: > > Il giorno gio 16 apr 2020 alle ore 01:13 Mikael Magnusson < > mikachu@gmail.com> > > ha scritto: > [...] > > > : ${(PA)varname::=$array} > > > (leave out the A for scalar assignment, and use AA for assoc arrays). > [...] > > Thanks! I was afraid I had to resort to eval. > [...] > > What's wrong with "eval"? Note that many of those alternatives > to "eval" are just other evals in disguise or are as dangerous > (but giving the wrong impression that they're not). > > : ${(PA)varname::=$array} > > is a command injection vulnerability if the content of $varname > is not sanitized. > > > $ varname='x[$(uname>&2)]' > $ : ${(PA)varname::=$array} > Linux > zsh: bad math expression: empty string > > So is: > > eval $varname'=("$array[@]")' > > but at least it's more obvious that it is. > > In any case, I'd expect the contents of $varname to be known and > trusted in this case, while that of $array could be anything. > > Note that that "$array[@]" (instead of $array) is needed to > preserve empty elements. > > -- > Stephane >
"Sanitizing" a varname for (P) expansion is context-dependent. For example, this is "legal": varname='x[$(echo 3)]' : ${(AP)varname::=foo} The point being, there's no straightforward internal test that zsh could apply to ${(P)varname} that would correctly reject "unsanitary" references. I suppose we could do something similar to Perl's taint checks and prevent (P) from being used on environment variables that have not been (re)assigned since the current shell started up.
[-- Attachment #1: Type: text/plain, Size: 849 bytes --] my personal sanitization test is: [[ ! $var =~ '^[a-zA-Z_][a-zA-Z_0-9]*$' ]] && { error "msg", return 1} Pier Paolo Grassi linkedin: https://www.linkedin.com/in/pier-paolo-grassi-19300217 founder: https://www.meetup.com/it-IT/Machine-Learning-TO Il giorno gio 16 apr 2020 alle ore 19:39 Bart Schaefer < schaefer@brasslantern.com> ha scritto: > "Sanitizing" a varname for (P) expansion is context-dependent. For > example, this is "legal": > > varname='x[$(echo 3)]' > : ${(AP)varname::=foo} > > The point being, there's no straightforward internal test that zsh > could apply to ${(P)varname} that would correctly reject "unsanitary" > references. I suppose we could do something similar to Perl's taint > checks and prevent (P) from being used on environment variables that > have not been (re)assigned since the current shell started up. >
[-- Attachment #1: Type: text/plain, Size: 1020 bytes --] >: ${(PA)varname::="$array[@]"} > >to not lose empty elements. this (very useful) clarification has made me embark in a three hour long quest to correct (some of?) the many places where I indeed was loosing empty elements thanks but I really hate when I find out bugs that i never have thought of (a big one has been discovering the -r flag to read) one should indeed always rtfm, and I really enjoy doing it, but there are so many to read and so few hours in a day... Pier Paolo Grassi Il giorno gio 16 apr 2020 alle ore 18:29 Sebastian Gniazdowski < sgniazdowski@gmail.com> ha scritto: > On Thu, 16 Apr 2020 at 01:14, Mikael Magnusson <mikachu@gmail.com> wrote: > >> : ${(PA)varname::=$array} >> (leave out the A for scalar assignment, and use AA for assoc arrays). >> > > I would do: > > : ${(PA)varname::="$array[@]"} > > to not lose empty elements. > > -- > Sebastian Gniazdowski > News: https://twitter.com/ZdharmaI > IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zinit > Blog: http://zdharma.org >
2020-04-16 20:04:57 +0200, Pier Paolo Grassi: [...] > thanks but I really hate when I find out bugs that i never have thought of > (a big one has been discovering the -r flag to read) [...] While you're there, note that the syntax to read a line of input verbatim is: IFS= read -r line not just read -r line. Compare: $ print -r ' a\b ' | IFS= read -r a; printf '<%s>\n' $a < a\b > $ print -r ' a\b ' | read -r a; printf '<%s>\n' $a <a\b> $ print -r ' a\b ' | read a; printf '<%s>\n' $a <ab> See https://unix.stackexchange.com/questions/209123/understanding-ifs-read-r-line for details. -- Stephane
[-- Attachment #1: Type: text/plain, Size: 1040 bytes --] thanks, fortunately I already crossed that bridge, as my read alias can testify: alias \read read='IFS='''' read -r' Pier Paolo Grassi linkedin: https://www.linkedin.com/in/pier-paolo-grassi-19300217 founder: https://www.meetup.com/it-IT/Machine-Learning-TO Il giorno gio 16 apr 2020 alle ore 22:24 Stephane Chazelas < stephane@chazelas.org> ha scritto: > 2020-04-16 20:04:57 +0200, Pier Paolo Grassi: > [...] > > thanks but I really hate when I find out bugs that i never have thought > of > > (a big one has been discovering the -r flag to read) > [...] > > While you're there, note that the syntax to read a line of input > verbatim is: > > IFS= read -r line > > not just read -r line. > > Compare: > > $ print -r ' a\b ' | IFS= read -r a; printf '<%s>\n' $a > < a\b > > $ print -r ' a\b ' | read -r a; printf '<%s>\n' $a > <a\b> > $ print -r ' a\b ' | read a; printf '<%s>\n' $a > <ab> > > See > https://unix.stackexchange.com/questions/209123/understanding-ifs-read-r-line > for details. > > -- > Stephane > -- Pier Paolo Grassi