Due to the fact that Bash, when operating in set -o nounset (aka set -u ) mode, can consider empty arrays as unset, regardless of whether they were really assigned an empty value, you should be careful when trying to expand the array - one of the workarounds is to check if the length of the array is equal to zero. Not to mention the fact that getting the number of elements in an array is a common operation in itself.
When developing with Bash 4.2.47 (1) -release in openSUSE 42.1, I got used to the fact that getting the size of the array using ${#ARRAY_NAME[@]} succeeds when the array is either empty or not defined. However, checking my script with Bash 4.3.46 (1) -release in FreeBSD 10.3, it turned out that this operation might fail with the general error message "unbound variable". Providing a default value for the extension does not seem to work for the length of the array. Providing alternative command chains seems to work, but not inside the function caused by the extension of the subnets - the functions just exit after the first failure. What else can help?
Consider the following example:
function Size () { declare VAR="$1" declare REF="\${#${VAR}[@]}" eval "echo \"${REF}\" || echo 0" 2>/dev/null || echo 0 } set -u declare -a MYARRAY echo "size: ${#MYARRAY[@]}" echo "size: ${#MYARRAY[@]-0}" echo "Size: $(Size 'MYARRAY')" echo -n "Size: "; Size 'MYARRAY'
In an openSUSE environment, all echo lines echo 0 , as expected. In FreeBSD, the same result is possible only when the array is explicitly assigned an empty value: MYARRAY=() ; otherwise, both inline queries in the first two lines fail, the third line simply displays Size: (which means that the result of the extension is empty), and only the last line completes completely thanks to the external || echo 0 || echo 0 , however, passing the result through to the screen is not what is usually assumed when trying to get the length of the array.
Here is a summary of my observations:
Bash 4.2 Bash 4.3 openSUSE FreeBSD counting elements of unset array OK FAILED counting elements of empty array OK OK content expansion of unset array FAILED FAILED content expansion of unset array(*) OK OK content expansion of empty array FAILED FAILED content expansion of empty array(*) OK OK (* with fallback value supplied)
For me it looks rather inconsistent. Is there any real future and cross-platform solution for this?
source share