2016-01-20 64 views
0

我已經成功地將單個數組作爲參數調用,但是我在通過多個數組時遇到了問題。以下是我迄今爲止:在bash中傳遞多個數組作爲參數

calling function { 
    array1=(1, 2, 3, 4) 
    array2=(a, b, c, d) 
    array3=(!, @, #, $) 

    called function() "${array1[@]" "${array2[@]}" "${array3[@]}" 
} 

called function { 
    local_array1=("${@}")  # i am guessing my problem lies here? 
    local_array2=("${@}")  
    local_array3=("${@}") 

    echo ${local_array1[@]} 
    echo ${local_array2[@]} 
    echo ${local_array3[@]} 
} 

回答

1

性狀第三陣列中具有特殊的意義,在bash,兩個第一陣列可以通過&打印:

#!/bin/bash 

called_function() 
{ 
    local local_array1=$1[@]  # i am guessing my problem lies here? 
    local local_array2=$2[@] 

    echo ${!local_array1} 
    echo ${!local_array2} 
} 

calling_function() 
{ 
    array1=(1, 2, 3, 4) 
    array2=(a, b, c, d) 

    called_function array1 array2 #array3 
} 

calling_function 

產生這樣的:

./test.sh 
1, 2, 3, 4 
a, b, c, d 
+0

傳遞參考?絕對聰明,但讀者應該意識到這與典型的按價值方法之間的語義差異。 –

3

函數或程序的參數列表是單個長陣列。當將三個不同的源數組連接到它上時,結果仍然只有一個參數列表,並且這三個數組的內容依次排列。

有兩種解決方案。最安全的一個是連接到一個單一的參數列表,並通過值傳遞參數,通過其長度前綴每個陣列:

caller() { 
    array1=(1 2 3 4) 
    array2=(a b c d) 
    array3=('!' '@' '#' '$') 

    callee \ 
     "${#array1[@]}" "${array1[@]}" \ 
     "${#array2[@]}" "${array2[@]}" \ 
     "${#array3[@]}" "${array3[@]}" 
} 

callee() { 
    # using declare -a makes the values truly local 
    # without local or declare they're actually global 
    declare -a local_array1=("${@:1:$1}"); shift "$(($1 + 1))" 
    declare -a local_array2=("${@:1:$1}"); shift "$(($1 + 1))" 
    declare -a local_array3=("${@:1:$1}"); shift "$(($1 + 1))" 

    printf 'array1 entry: %q\n' "${local_array1[@]}" 
    printf 'array2 entry: %q\n' "${local_array2[@]}" 
    printf 'array3 entry: %q\n' "${local_array3[@]}" 
} 

另一種方法是通過引用傳遞。如果你有bash的4.3,你可以使用一個新的shell功能,稱爲namevars,首先由KSH實施明確用於此目的:

caller() { 
    array1=(1 2 3 4) 
    array2=(a b c d) 
    array3=('!' '@' '#' '$') 

    callee array1 array2 array3 
} 

callee() { 
    declare -n local_array1=$1 
    declare -n local_array2=$2 
    declare -n local_array3=$3 

    printf 'array1 entry: %q\n' "${local_array1[@]}" 
    printf 'array2 entry: %q\n' "${local_array2[@]}" 
    printf 'array3 entry: %q\n' "${local_array3[@]}" 
} 

然而,通過按引用是略遜一籌:這取決於變量範圍是可以隨處訪問,並且被調用者可以修改調用者中數組的值(實際上,當使用此處顯示的bash-4.3 namevar方法時,該行爲是自動的:對local_array1的任何更改也將修改array1)。