unsetting associative array executes commands

2021-03-11 Thread Jason A. Donenfeld
This behavior is quite surprising:

$ declare -A blah
$ blah['$(DOESNOTEXIST)']=broken
$ for i in "${!blah[@]}"; do echo "$i"; done
$(DOESNOTEXIST)
$ for i in "${!blah[@]}"; do unset blah["$i"]; done
bash: DOESNOTEXIST: command not found
bash: unset: [$(DOESNOTEXIST)]: bad array subscript

I wouldn't have anticipated the double expansion of "$i" there.

Is this a bug? Bash 5.1p4.



Re: unsetting associative array executes commands

2021-03-11 Thread Greg Wooledge
On Thu, Mar 11, 2021 at 08:06:55AM -0700, Jason A. Donenfeld wrote:
> This behavior is quite surprising:
> 
> $ declare -A blah
> $ blah['$(DOESNOTEXIST)']=broken
> $ for i in "${!blah[@]}"; do echo "$i"; done
> $(DOESNOTEXIST)
> $ for i in "${!blah[@]}"; do unset blah["$i"]; done
> bash: DOESNOTEXIST: command not found
> bash: unset: [$(DOESNOTEXIST)]: bad array subscript

unicorn:~$ declare -A blah
unicorn:~$ blah['$(DOESNOTEXIST)']=broken
unicorn:~$ for i in "${!blah[@]}"; do unset 'blah[$i]'; done
unicorn:~$ declare -p blah
declare -A blah=()



so-called pipe files (sh-np-*) do not get deleted when processes close.

2021-03-11 Thread Michael Felt

Hi,

Issue: AdoptOpenJDK build process makes bash calls in a particular way. 
An abbreviated (shorter pathnames) example is:


```
bash-5.0$ /usr/bin/printf "Building targets 'product-images 
legacy-jre-image test-image' in configuration 
'aix-ppc64-normal-server-release'\n" > >(/usr/bin/tee -a 
/home/aixtools/build.log) 2> >(/usr/bin/tee -a /home/aixtools/build.log >&2)
Building targets 'product-images legacy-jre-image test-image' in 
configuration 'aix-ppc64-normal-server-release'


```

back to ksh:
```
$ cat ~/build.log
Building targets 'product-images legacy-jre-image test-image' in 
configuration 'aix-ppc64-normal-server-release'


```

I added some debug statements to try and catch what is not happening. It 
seems that the fifo_list[i].proc value is never being set to (pid_t)-1 
so any call to `unlink_fifo()` or `unlink_fifo_list()` does not unlink 
the special file created.


I have forced some debug info:

a) unset USE_MKTEMP
b) added the PID of the process creating the special file
c) additional debug info using fprintf(FILE, ...)

    fprintf(unlink_lst,"%d:%s:%d:%16s:%2d:%12d:%s\n", getpid(), 
__FILE__, __LINE__, "unlink_fifo_list", i, fifo_list[i].proc, 
fifo_list[i].file);



That gives me the following information from the command above:

25231596:../src/bash-5.0.18/execute_cmd.c:752:execute_command_internal:/usr/bin/printf 
"Building targets 'product-images legacy-jre-image test-image' in 
configuration 'aix-ppc64-normal-server-release'\n" > >(/usr/bin/tee -a 
/home/aixtools/build.log) 2> >(/usr/bin/tee -a /home/aixtools/build.log >&2)
21233868:../src/bash-5.0.18/subst.c:5372:   add_fifo_list: 0:   
0:/tmp//sh-np-21233868-1115804781
27918500:../src/bash-5.0.18/execute_cmd.c:752:execute_command_internal:/usr/bin/tee 
-a /home/aixtools/build.log
21233868:../src/bash-5.0.18/subst.c:5372:   add_fifo_list: 1:   
0:/tmp//sh-np-21233868-3761770506

27918500:../src/bash-5.0.18/subst.c:5506:reap_procsubs-calls:23
27918500:../src/bash-5.0.18/subst.c:5510:   unlink_if==-1: 0:   
0:/tmp//sh-np-21233868-1115804781
26869806:../src/bash-5.0.18/execute_cmd.c:752:execute_command_internal:/usr/bin/tee 
-a /home/aixtools/build.log 1>&2

26869806:../src/bash-5.0.18/subst.c:5506:reap_procsubs-calls:23
26869806:../src/bash-5.0.18/subst.c:5510:   unlink_if==-1: 0: 
27918500:/tmp//sh-np-21233868-1115804781
26869806:../src/bash-5.0.18/subst.c:5510:   unlink_if==-1: 1:   
0:/tmp//sh-np-21233868-3761770506


And this is remaining:
$ ls -l /tmp/sh-np* | grep 21233868
prw---    1 aixtools staff 0 Mar 11 08:07 
/tmp/sh-np-21233868-1115804781
prw---    1 aixtools staff 0 Mar 11 08:07 
/tmp/sh-np-21233868-3761770506



Getting back to AdoptOpenJDK - a build process has roughly 3750 of these 
commands - leaving 7500 files behind in /tmp. On a busy day this can 
lead to over 100k empty files in /tmp.


Thanks for any assistance.

Regards,

Michael




OpenPGP_0x722BFDB61F396FC2.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


Re: unsetting associative array executes commands

2021-03-11 Thread Jason A. Donenfeld
Single quotes with the nested double quote? That's nuts. But okay. I
guess there really is some double expansion eval-like logic happening
with the unset operator.



Re: unsetting associative array executes commands

2021-03-11 Thread Greg Wooledge
On Thu, Mar 11, 2021 at 09:38:37AM -0700, Jason A. Donenfeld wrote:
> Single quotes with the nested double quote? That's nuts. But okay. I
> guess there really is some double expansion eval-like logic happening
> with the unset operator.

I removed the double quotes, as they serve no purpose there.

For an indexed array, use:  unset 'a[i]'
For an associative array, use:  unset 'a[$i]'

In both cases, use single quotes, and all will be well.

(In the indexed array case, there is another pitfall involving code
injection in the arithmetic context, so only use sanitized index values.)



Re: so-called pipe files (sh-np-*) do not get deleted when processes close.

2021-03-11 Thread Chet Ramey

On 3/11/21 11:28 AM, Michael Felt wrote:

Hi,

Issue: AdoptOpenJDK build process makes bash calls in a particular way. An 
abbreviated (shorter pathnames) example is:


```
bash-5.0$ /usr/bin/printf "Building targets 'product-images 
legacy-jre-image test-image' in configuration 
'aix-ppc64-normal-server-release'\n" > >(/usr/bin/tee -a 
/home/aixtools/build.log) 2> >(/usr/bin/tee -a /home/aixtools/build.log >&2)
Building targets 'product-images legacy-jre-image test-image' in 
configuration 'aix-ppc64-normal-server-release'


I believe this is fixed in bash-5.1.


I added some debug statements to try and catch what is not happening. It 
seems that the fifo_list[i].proc value is never being set to (pid_t)-1 so 
any call to `unlink_fifo()` or `unlink_fifo_list()` does not unlink the 
special file created.


Probably because the process substitution does not exit before the shell does.

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: unsetting associative array executes commands

2021-03-11 Thread Chet Ramey

On 3/11/21 10:06 AM, Jason A. Donenfeld wrote:

This behavior is quite surprising:


The idea is that array subscripts undergo a uniform set of expansions when
they're used, no matter the context. Builtins already undergo word 
expansions as part of command execution. The result is double expansion

in certain cases (there are more; this is a staple of discussion here on
the list).

You can use the `assoc_expand_once' shell option to reduce the number of
expansions; it would have prevented the behavior you observed here, for
instance. But it's not perfect, as many people on the list will tell you.



$ declare -A blah
$ blah['$(DOESNOTEXIST)']=broken
$ for i in "${!blah[@]}"; do echo "$i"; done
$(DOESNOTEXIST)
$ for i in "${!blah[@]}"; do unset blah["$i"]; done
bash: DOESNOTEXIST: command not found
bash: unset: [$(DOESNOTEXIST)]: bad array subscript



$ cat x1
declare -A blah
blah['$(DOESNOTEXIST)']=broken
shopt -s assoc_expand_once
for i in "${!blah[@]}"; do unset blah["$i"]; done
declare -p blah
$ ../bash-5.1-patched/bash ./x1
declare -A blah=()


--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: unsetting associative array executes commands

2021-03-11 Thread Chet Ramey

On 3/11/21 11:38 AM, Jason A. Donenfeld wrote:

Single quotes with the nested double quote? That's nuts. But okay. I
guess there really is some double expansion eval-like logic happening
with the unset operator.


It's not an `operator' per se, it's a builtin command. That means its
arguments undergo the standard word expansions before `unset' even sees
them.

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: unsetting associative array executes commands

2021-03-11 Thread Alex fxmbsw7 Ratchev
maybe implent a shopt -s no_expand_subshells

On Thu, Mar 11, 2021 at 9:20 PM Chet Ramey  wrote:

> On 3/11/21 10:06 AM, Jason A. Donenfeld wrote:
> > This behavior is quite surprising:
>
> The idea is that array subscripts undergo a uniform set of expansions when
> they're used, no matter the context. Builtins already undergo word
> expansions as part of command execution. The result is double expansion
> in certain cases (there are more; this is a staple of discussion here on
> the list).
>
> You can use the `assoc_expand_once' shell option to reduce the number of
> expansions; it would have prevented the behavior you observed here, for
> instance. But it's not perfect, as many people on the list will tell you.
>
> >
> > $ declare -A blah
> > $ blah['$(DOESNOTEXIST)']=broken
> > $ for i in "${!blah[@]}"; do echo "$i"; done
> > $(DOESNOTEXIST)
> > $ for i in "${!blah[@]}"; do unset blah["$i"]; done
> > bash: DOESNOTEXIST: command not found
> > bash: unset: [$(DOESNOTEXIST)]: bad array subscript
>
>
> $ cat x1
> declare -A blah
> blah['$(DOESNOTEXIST)']=broken
> shopt -s assoc_expand_once
> for i in "${!blah[@]}"; do unset blah["$i"]; done
> declare -p blah
> $ ../bash-5.1-patched/bash ./x1
> declare -A blah=()
>
>
> --
> ``The lyf so short, the craft so long to lerne.'' - Chaucer
>  ``Ars longa, vita brevis'' - Hippocrates
> Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
>
>


Re: unsetting associative array executes commands

2021-03-11 Thread Andreas Schwab
On Mär 11 2021, Chet Ramey wrote:

> $ cat x1
> declare -A blah
> blah['$(DOESNOTEXIST)']=broken
> shopt -s assoc_expand_once
  touch blah\$
> for i in "${!blah[@]}"; do unset blah["$i"]; done
> declare -p blah
> $ ../bash-5.1-patched/bash ./x1
> declare -A blah=()

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."



Re: so-called pipe files (sh-np-*) do not get deleted when processes close.

2021-03-11 Thread Michael Felt (aixtools)


Sent from my iPhone

> On 11 Mar 2021, at 18:15, Chet Ramey  wrote:
> 
> On 3/11/21 11:28 AM, Michael Felt wrote:
>> Hi,
>> Issue: AdoptOpenJDK build process makes bash calls in a particular way. An 
>> abbreviated (shorter pathnames) example is:
>> ```
>> bash-5.0$ /usr/bin/printf "Building targets 'product-images legacy-jre-image 
>> test-image' in configuration 'aix-ppc64-normal-server-release'\n" > 
>> >(/usr/bin/tee -a /home/aixtools/build.log) 2> >(/usr/bin/tee -a 
>> /home/aixtools/build.log >&2)
>> Building targets 'product-images legacy-jre-image test-image' in 
>> configuration 'aix-ppc64-normal-server-release'
> 
> I believe this is fixed in bash-5.1.
Would it be difficult to give me a hint for 5.0. I could test further now i 
have a command that generates the issue. 
> 
> 
>> I added some debug statements to try and catch what is not happening. It 
>> seems that the fifo_list[i].proc value is never being set to (pid_t)-1 so 
>> any call to `unlink_fifo()` or `unlink_fifo_list()` does not unlink the 
>> special file created.
> 
> Probably because the process substitution does not exit before the shell does.
I was hoping that is what the wait routines were for. Also noticed that the 
second fifo never gets a pid. 
> -- 
> ``The lyf so short, the craft so long to lerne.'' - Chaucer
>``Ars longa, vita brevis'' - Hippocrates
> Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/




Re: unsetting associative array executes commands

2021-03-11 Thread Koichi Murase
2021年3月12日(金) 4:37 Alex fxmbsw7 Ratchev :
> maybe implent a shopt -s no_expand_subshells

There is already `shopt -s assoc_expand_once'. With this shell option,
one can write `unset "blah[$i]"'.

But such an option actually doesn't completely solve all similar cases
including the associative array access in arithmetic contexts. Instead
one can always write as

$ unset 'blah[$i]'
$ ((blah[\$i]))
$ etc.

Also, there was a thread on exactly the same topic last week:
https://lists.gnu.org/archive/html/bug-bash/2021-03/msg4.html
https://lists.gnu.org/archive/html/bug-bash/2021-03/msg5.html
https://lists.gnu.org/archive/html/bug-bash/2021-03/msg8.html

--
Koichi



Re: unsetting associative array executes commands

2021-03-11 Thread Chet Ramey

On 3/11/21 3:50 PM, Andreas Schwab wrote:

On Mär 11 2021, Chet Ramey wrote:


$ cat x1
declare -A blah
blah['$(DOESNOTEXIST)']=broken
shopt -s assoc_expand_once

   touch blah\$

for i in "${!blah[@]}"; do unset blah["$i"]; done
declare -p blah
$ ../bash-5.1-patched/bash ./x1
declare -A blah=()


Sure:

"When  using  a  variable name with a subscript as an argument to a com-
 mand, such as with unset, without using the word expansion  syntax  de-
 scribed above, the argument is subject to pathname expansion.  If path-
 name expansion is not desired, the argument should be quoted."


--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: so-called pipe files (sh-np-*) do not get deleted when processes close.

2021-03-11 Thread Chet Ramey

On 3/11/21 3:55 PM, Michael Felt (aixtools) wrote:



Sent from my iPhone


On 11 Mar 2021, at 18:15, Chet Ramey  wrote:

On 3/11/21 11:28 AM, Michael Felt wrote:

Hi,
Issue: AdoptOpenJDK build process makes bash calls in a particular way. An 
abbreviated (shorter pathnames) example is:
```
bash-5.0$ /usr/bin/printf "Building targets 'product-images legacy-jre-image test-image' in 
configuration 'aix-ppc64-normal-server-release'\n" > >(/usr/bin/tee -a /home/aixtools/build.log) 
2> >(/usr/bin/tee -a /home/aixtools/build.log >&2)
Building targets 'product-images legacy-jre-image test-image' in configuration 
'aix-ppc64-normal-server-release'


I believe this is fixed in bash-5.1.

Would it be difficult to give me a hint for 5.0. I could test further now i 
have a command that generates the issue.


I can't reproduce it, but you can look at unlink_all_fifos() in bash-5.1.
It's defined in subst.c and called in shell.c.


Probably because the process substitution does not exit before the shell does.

I was hoping that is what the wait routines were for. Also noticed that the 
second fifo never gets a pid.


Bash doesn't wait for asynchronous processes before it exits unless you use
`wait'.


--
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/