Bug 1109736

Summary: Undocumented behaviour change in bash 4.3
Product: [Fedora] Fedora Reporter: Simone Caronni <negativo17>
Component: bashAssignee: Ondrej Oprala <ooprala>
Status: CLOSED NOTABUG QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: rawhideCC: admiller, ooprala, ovasik, raselmsh, robatino
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2014-06-17 13:26:04 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1104253    

Description Simone Caronni 2014-06-16 09:36:00 UTC
Description of problem:
Different undocumented behaviour change

Version-Release number of selected component (if applicable):
bash-4.3.18-2

How reproducible:
Always

Steps to Reproduce:
Affected example command:

bash -x -c 'arr[0]=; arr[1]=; [[ ${arr[@]} ]] || echo false'

1. Run the command on Fedora 21 with bash-4.3.18-2
2. Run the same commmand in Fedora 20 or Ubuntu (bash 4.3.11)

Results:
Result is "true", which is not as expected as the same command returns "fals" from RHEL 5 to Fedora 20.

Additional info:
Couldn't find any documentation or changelog regarding this change. This breaks a lot of scripts. Also setting BASH_COMPAT to 4.2 does not revert to the original behaviour.

Fedora 20 output:

$ bash -x -c 'arr[0]=; arr[1]=; [[ ${arr[@]} ]] || echo false' 
+ arr[0]=
+ arr[1]=
+ [[ -n '' ]]
+ echo false
false

Fedora rawhide output:

$ bash -x -c 'arr[0]=; arr[1]=; [[ ${arr[@]} ]] || echo false' 
+ arr[0]=
+ arr[1]=
+ [[ -n   ]]

Comment 2 Ondrej Oprala 2014-06-17 13:07:43 UTC
Michael is right, this was buggy behaviour fixed by patchlevel 14.

To explain:
According to man pages, ${arr[@]} expands the array into separate words (analogous to the expansion of $@). Quoting the man page: 'That is, "$@" is equivalent to "$1" "$2" ...' So what it basically becomes in your example is <value-of-arr0><separator><value-of-arr1>.

Substituting the relevant piece of code with [[ \"${arr[@]}\\" ]] demonstrates this well.

There are minor distinctions in expanding using * and @.
The man page states:
"If the word is double-quoted, ${name[*]} expands to a single word with the value of each array member separated by the first character of the IFS special  variable".

Meaning, the correct way to write your example line and get the behaviour you want is:
bash -x -c 'IFS=; arr[0]=; arr[1]=; [[ "${arr[*]}" ]] || echo false'

Comment 3 Ondrej Oprala 2014-06-17 13:09:57 UTC
Correction:
Substituting the relevant piece of code with [[ \"${arr[@]}\" ]] demonstrates this well.

Comment 4 Simone Caronni 2014-06-17 13:26:04 UTC
Thanks for the explanation. This is really big, we probably need to audit all the code as this has been built on foundations like this since 2000'.

Comment 5 Ondrej Oprala 2014-06-17 13:31:26 UTC
No problem. And yes, it's actually the most common use, that's always been the undocumented one :/ .