Bug 1109736 - Undocumented behaviour change in bash 4.3
Summary: Undocumented behaviour change in bash 4.3
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: bash
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Ondrej Oprala
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: 1104253
TreeView+ depends on / blocked
 
Reported: 2014-06-16 09:36 UTC by Simone Caronni
Modified: 2016-02-01 02:09 UTC (History)
5 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2014-06-17 13:26:04 UTC


Attachments (Terms of Use)


Links
System ID Priority Status Summary Last Updated
VirtualBox 13097 None None None Never

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 :/ .


Note You need to log in before you can comment on or make changes to this bug.