I have the following bash script:
#!/bin/bash
encl0=( 0,0 0,1 0,2 0,3 0,4 0,5 0,7 0,8 0,9 0,10 0,11 0,12 0,13 0,14 0,15 )
MISSING_DISKS=()
OLDIFS=$IFS
IFS=$'\n'
MISSING_DISKS+=($({ printf '0 %s\n' {0..15}; printf '0 %s\n' "${encl0[@]#0,}"; } | sort | uniq -u))
IFS=$OLDIFS
echo "$({ printf '0 %s\n' {0..15}; printf '0 %s\n' "${encl0[@]#0,}"; } | sort | uniq -u)"
echo "${MISSING_DISKS[@]}"
if ((${#MISSING_DISKS[@]}>1)); then
echo "Greater than 1"
else
echo "Success"
fi
When I run it with bash v4.4 it works as I expect:
$ /usr/local/bin/bash test.sh
0 6
0 6
Success
However when I run it with bash v3.2 it does not:
$ /bin/bash test.sh
0 6
0 0 0 0 1 2 3 4 5 7 8 9 10 11 12 13 14 15 0 1 0 10 0 11 0 12 0 13 0 14 0 15 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9
Greater than 1
I don't understand how MISSING_DISKS
is being set to something different than the output of the command that is setting it though. Does anyone know what is causing this?
Best Answer
Playing with spaces, tabs or newlines is always close to failure.
The core problem occurs here:
If executed on bash 3.2:
The expansion of
"${encl0[@]#0,}"
is processed as one string, not a list of values.The problem doesn't manifest if either the IFS has an space or if the expansion does not edit each value of the array:
Executed:
Or:
Executed:
The problem is hidden in your script because you restore IFS
IFS=$OLDIFS
before the testing echo line.One way to avoid the issue is to not use an space in the printf:
The other alternative is to avoid the expansion with substitution after changing the IFS to a newline by using an alternate array:
I recommend you that:
+=
an array that is empty at that point in the codeMISSING_DISKS+=
.If those changes are done, the script becomes: