Unsetting all elements of an associative array
I'm trying to use unset array[@] to empty an associative array, but something goes wrong. This behaves as expected: $ declare -A array; array[path/directory]=value This produces an error: $ declare -A array; unset array[@]; array[path/directory]=value bash: path/directory: division by 0 (error token is "directory") After unsetting all its elements, the array is not associative anymore? Using array=() empties the array correctly.
Re: Unsetting all elements of an associative array
On Wed, Feb 04, 2015 at 09:12:12AM +0100, isabella parakiss wrote: > I'm trying to use unset array[@] to empty an associative array, but something > goes wrong. What caused you to believe that would work? > This produces an error: > $ declare -A array; unset array[@]; array[path/directory]=value > bash: path/directory: division by 0 (error token is "directory") unset 'array[@]' appears to be exactly the same as unset 'array'. It completely eradicates the entire array, including the declaration that it is associative. Then when you do array[a/b]=c you are creating a new integer-indexed array. [a/b] becomes a math context, so it tries to divide the value of a by the value of b (using 0 if either of those is not set). On that note, today I learned that you are not allowed to use either * or @ as the index of an associative array in bash. I guess I can see why, but... that's probably going to break something some day.
Re: Unsetting all elements of an associative array
On 2/4/15 8:39 AM, Greg Wooledge wrote: > On that note, today I learned that you are not allowed to use either * > or @ as the index of an associative array in bash. What caused you to believe that would work? -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
Re: Unsetting all elements of an associative array
On Wed, Feb 4, 2015 at 2:39 PM, Greg Wooledge wrote: > On that note, today I learned that you are not allowed to use either * > or @ as the index of an associative array in bash. I guess I can see why, > but... that's probably going to break something some day. :) of course you can ;-) declare -A a; a["@"]="right"; a["*"]="hoping that you are in an empty directory"; cheers, pg
Re: Unsetting all elements of an associative array
On Wed, Feb 04, 2015 at 03:37:07PM +0100, Piotr Grzybowski wrote: > On Wed, Feb 4, 2015 at 2:39 PM, Greg Wooledge wrote: > > > On that note, today I learned that you are not allowed to use either * > > or @ as the index of an associative array in bash. I guess I can see why, > > but... that's probably going to break something some day. > > :) > of course you can ;-) > > declare -A a; a["@"]="right"; a["*"]="hoping that you are in an empty > directory"; Huh, that's even stranger than I thought. imadev:~$ unset a; declare -A a; a=(["@"]=foo [!]=bar); declare -p a declare -A a='([@]="foo" ["!"]="bar" )' imadev:~$ unset a; declare -A a='([@]="foo" ["!"]="bar" )' bash: [@]="foo": invalid associative array key If the declare -p output is intended to be reusable shell code, then this is surely a bug. (Bash 4.3.30.)
Re: Unsetting all elements of an associative array
I think you are right, maybe this one should be considered: diff --git a/lib/sh/shquote.c b/lib/sh/shquote.c index fff4f81..de05f27 100644 --- a/lib/sh/shquote.c +++ b/lib/sh/shquote.c @@ -293,7 +293,7 @@ sh_contains_shell_metas (string) case '(': case ')': case '<': case '>': case '!': case '{': case '}': /* reserved words */ case '*': case '[': case '?': case ']': /* globbing chars */ - case '^': + case '^': case '@': case '$': case '`': /* expansion chars */ return (1); case '~': /* tilde expansion */ what do you think? cheers, pg On Wed, Feb 4, 2015 at 3:42 PM, Greg Wooledge wrote: > On Wed, Feb 04, 2015 at 03:37:07PM +0100, Piotr Grzybowski wrote: >> On Wed, Feb 4, 2015 at 2:39 PM, Greg Wooledge wrote: >> >> > On that note, today I learned that you are not allowed to use either * >> > or @ as the index of an associative array in bash. I guess I can see why, >> > but... that's probably going to break something some day. >> >> :) >> of course you can ;-) >> >> declare -A a; a["@"]="right"; a["*"]="hoping that you are in an empty >> directory"; > > Huh, that's even stranger than I thought. > > imadev:~$ unset a; declare -A a; a=(["@"]=foo [!]=bar); declare -p a > declare -A a='([@]="foo" ["!"]="bar" )' > > imadev:~$ unset a; declare -A a='([@]="foo" ["!"]="bar" )' > bash: [@]="foo": invalid associative array key > > If the declare -p output is intended to be reusable shell code, then > this is surely a bug. (Bash 4.3.30.)
Re: If $HISTFILE is set to /dev/null and you execute more commands than $HISTFILESIZE, /dev/null is deleted.
On 2/1/15 1:52 AM, Jonathan Hankins wrote: > ​Right. My concern is that a potential exploit could inject a malicious > value for HISTFILE into the environment. I think (but may be wrong) that > HISTFILE is the only codepath in a default shell invocation that could > result in a silent writing to an arbitrary file without direct action on > the part of the user. If I can inject arbitrary variables into the environment, I'm not going to mess around with HISTFILE. I'm going straight to LD_PRELOAD or maybe LD_LIBRARY_PATH, game over. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
Re: Unsetting all elements of an associative array
On Wed, Feb 4, 2015 at 4:12 PM, isabella parakiss wrote: > This produces an error: > $ declare -A array; unset array[@]; array[path/directory]=value > bash: path/directory: division by 0 (error token is "directory") > > After unsetting all its elements, the array is not associative anymore? Logically that should only unset the elements of an array and not the array variable itself since '*' or '@' is more of a wildcard that represents the indices. However, bash does otherwise: #define ALL_ELEMENT_SUB(c)((c) == '@' || (c) == '*') ... if (ALL_ELEMENT_SUB (sub[0]) && sub[1] == 0) // If substring is just '@' or '*' { unbind_variable (var->name); // It just removes it. return (0); } Bash version is 4.3.33.
Re: Unsetting all elements of an associative array
On 2/4/15 9:42 AM, Greg Wooledge wrote: > imadev:~$ unset a; declare -A a; a=(["@"]=foo [!]=bar); declare -p a > declare -A a='([@]="foo" ["!"]="bar" )' > > imadev:~$ unset a; declare -A a='([@]="foo" ["!"]="bar" )' > bash: [@]="foo": invalid associative array key > > If the declare -p output is intended to be reusable shell code, then > this is surely a bug. (Bash 4.3.30.) You're right, it should be quoted. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
Re: Unsetting all elements of an associative array
On 2/4/15 10:27 AM, Piotr Grzybowski wrote: > I think you are right, maybe this one should be considered: > > diff --git a/lib/sh/shquote.c b/lib/sh/shquote.c > index fff4f81..de05f27 100644 > --- a/lib/sh/shquote.c > +++ b/lib/sh/shquote.c > @@ -293,7 +293,7 @@ sh_contains_shell_metas (string) > case '(': case ')': case '<': case '>': > case '!': case '{': case '}': /* reserved words */ > case '*': case '[': case '?': case ']': /* globbing chars */ > - case '^': > + case '^': case '@': > case '$': case '`': /* expansion chars */ > return (1); > case '~': /* tilde expansion */ > > what do you think? It's a two-line fix, but that's the wrong place. Chet -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/ *** ../bash-4.3-patched/assoc.c 2011-11-05 16:39:05.0 -0400 --- assoc.c 2015-02-04 15:28:25.0 -0500 *** *** 437,440 --- 440,445 if (sh_contains_shell_metas (tlist->key)) istr = sh_double_quote (tlist->key); + else if (ALL_ELEMENT_SUB (tlist->key[0]) && tlist->key[1] == '\0') + istr = sh_double_quote (tlist->key); else istr = tlist->key;