Linux 命令精选--如何将数组传入到函数中

方法1.

takes_ary_as_arg()
{
    declare -a argAry1=("${!1}")
    echo "${argAry1[@]}"

    declare -a argAry2=("${!2}")
    echo "${argAry2[@]}"
}
try_with_local_arys()
{
    array variables could have local scope
    local descTable=(
        "sli4-iread"
        "sli4-iwrite"
        "sli3-iread"
        "sli3-iwrite"
    )
    local optsTable=(
        "--msix  --iread"
        "--msix  --iwrite"
        "--msi   --iread"
        "--msi   --iwrite"
    )
    takes_ary_as_arg descTable[@] optsTable[@] ##这里两个参数是字符串类型
}
try_with_local_arys
exit 0
针对方法1的解释:
The "takes_ary_as_arg descTable[@] optsTable[@]" line in try_with_local_arys() function sends

This is actually creates a copy of the descTable and optsTable arrays which are accessible to the takes_ary_as_arg function.
takes_ary_as_arg() function receives descTable[@] optsTable[@] as strings, that means $1 == descTable[@] and $2 == optsTable[@].
in the beginning of takes_ary_as_arg() function it uses ${!parameter} syntax, which is called indirect reference or sometimes double referenced, this means that instead of using $1's value, we use the value of the expanded value of $1, example:

baba=booba
variable=baba
echo ${variable} # baba
echo ${!variable} # booba
likewise for $2.

putting this in argAry1=("${!1}") creates argAry1 as an array (the brackets following =) with the expanded descTable[@], just like writing there argAry1=("${descTable[@]}") directly. the "declare" there is not required.
It is worth mentioning that array initialization using this bracket form initializes the new array according to the IFS or Internal Field Separator which is by default tab, newline and space. in that case, since it used "[@]" notation each element is seen by itself as if he was quoted (contrary to "[*]").


My reservation with it:

In BASH, local variable scope is the current function and every child function called from it, this translates to the fact that "takes_ary_as_arg()" function "sees" those descTable[@] and optsTable[@] arrays, thus it is working (see above explanation).

Being that case, why not directly look at those variables themselves? It is just like writing there:

argAry1=("${descTable[@]}")
(see above explanation) which just copies descTable[@] array's values according to the current IFS.

In summery: this is passing, in essence, nothing by value - as usual.

I also want to emphasize Dennis Williamson comment above: "sparse" arrays (arrays without all the keys defines - with "holes" in them) will not work as expected - we would loose the keys and "condense" the array.

That being said, I do see the value for generalization, functions thus can get the arrays (or copies) without knowing the names:

for ~"copies": this technique is good enough, just need to keep aware, that the indices (keys) are gone.
for real copies: we can use an eval for the keys, for example:

eval local keys=(\${!$1})
and then a loop using them to create a copy. Note: here '!' is not used it it's previous indirect/double evaluation, but rather in array context it returns the array indices (keys).

and, of course, if we were to pass descTable and optsTable strings (without [@]), we could use the array itself (as in by reference) with eval. for a generic function that accepts arrays.


方法2.

function print_array  {
        array_name=$1
        eval echo \${$array_name[*]}
        return
}

colors[0]="Pink"
colors[1]="Light Gray"
colors[2]="Green"

print_array colors
exit 0
方法3.
function print_array {
    # Setting the shell's Internal Field Separator to null
    OLD_IFS=$IFS
    IFS=''

    # Create a string containing "colors[*]"
    local array_string="$1[*]"
	debug "array_string=$array_string"

    # assign loc_array value to ${colors[*]} using indirect variable reference
    local loc_array=(${!array_string})

    # Resetting IFS to default
    IFS=$OLD_IFS

    # Checking the second element "Light Gray" (the one with a space)
    echo ${loc_array[1]} 
}

# create an array and display contents
colors=('Pink' 'Light Gray' 'Green')
echo ${colors[*]}

# call function with positional parameter $1 set to array's name
print_array colors 

# checking whether the function "local" loc_array is visible here
echo "Does the local array exist here? -->${loc_array[*]}<--"
exit 0

你可能感兴趣的:(Linux 命令精选--如何将数组传入到函数中)