2013-05-09 43 views
36

Như chúng ta biết, trong lập trình bash, cách vượt qua đối số là $1, ..., $N. Tuy nhiên, tôi thấy nó không dễ dàng để vượt qua một mảng như một đối số cho một hàm nhận nhiều hơn một đối số. Dưới đây là một ví dụ:Cách chuyển mảng làm đối số cho hàm trong Bash

f(){ 
x=($1) 
y=$2 

for i in "${x[@]}" 
do 
    echo $i 
done 
.... 
} 

a=(“jfaldsj jflajds" "LAST") 
b=NOEFLDJF 

f "${a[@]}" $b 
f "${a[*]}" $b 

Như đã trình bày, chức năng f nhận hai đối số: là người đầu tiên được gán cho x mà là một mảng, thứ hai để y.

f có thể được gọi theo hai cách. Cách đầu tiên sử dụng "${a[@]}" như là đối số đầu tiên, và kết quả là:

jfaldsj 
jflajds 

Cách thứ hai sử dụng "${a[*]}" như là đối số đầu tiên, và kết quả là:

jfaldsj 
jflajds 
LAST 

kết quả Không phải là như Tôi ước. Vì vậy, có ai có bất kỳ ý tưởng về làm thế nào để vượt qua mảng giữa các chức năng một cách chính xác?

+1

có thể trùng lặp của [Truyền mảng dưới dạng tham số trong bash] (http://stackoverflow.com/questions/1063347/passing-arrays-as-parameters-in-bash) – chepner

+0

@chepner cảm ơn vì đã nhắc nhở. Tôi sẽ kiểm tra sau này để biết một số ý tưởng –

+0

http://stackoverflow.com/questions/1063347/passing-arrays-as-parameters-in-bash –

Trả lời

59

Bạn không thể chuyển mảng, bạn chỉ có thể chuyển các phần tử của nó (tức là mảng mở rộng).

#! /bin/bash 
function f() { 
    a=("[email protected]") 
    ((last_idx=${#a[@]} - 1)) 
    b=${a[last_idx]} 
    unset a[last_idx] 

    for i in "${a[@]}" ; do 
     echo "$i" 
    done 
    echo "b: $b" 
} 

x=("one two" "LAST") 
b='even more' 

f "${x[@]}" "$b" 
echo =============== 
f "${x[*]}" "$b" 

Khả năng khác sẽ được vượt qua mảng theo tên:

#! /bin/bash 
function f() { 
    name=$1[@] 
    b=$2 
    a=("${!name}") 

    for i in "${a[@]}" ; do 
     echo "$i" 
    done 
    echo "b: $b" 
} 

x=("one two" "LAST") 
b='even more' 

f x "$b" 
+0

chuyển mảng theo tên? bạn có thể làm cho nó rõ ràng hơn không. Tôi tìm thấy bạn chỉ cần làm cho nó có thể –

+0

@RedLv: Chỉ cần vượt qua tên của mảng và sử dụng mở rộng tham số với '!' Để lấy mảng. – choroba

+7

lưu ý rằng giá trị của biến "name" chỉ là chuỗi "x [@]". Phép thuật xảy ra với '$ {! ...} ' –

5

Bạn có thể vượt qua giá trị "vô hướng" đầu tiên. Điều đó sẽ đơn giản hóa mọi thứ:

f(){ 
    b=$1 
    shift 
    a=("[email protected]") 

    for i in "${a[@]}" 
    do 
    echo $i 
    done 
    .... 
} 

a=("jfaldsj jflajds" "LAST") 
b=NOEFLDJF 

f "$b" "${a[@]}" 

Tại thời điểm này, bạn cũng có thể sử dụng các params vị trí mảng-ish trực tiếp

f(){ 
    b=$1 
    shift 

    for i in "[email protected]" # or simply "for i; do" 
    do 
    echo $i 
    done 
    .... 
} 

f "$b" "${a[@]}" 
+1

Ý tưởng của bạn có thể hoạt động trong trường hợp này. Tuy nhiên nó không nhấn điểm của mảng đi qua như là đối số. –

0

này sẽ giải quyết vấn đề thông qua mảng hoạt động:

#!/bin/bash 
foo() 
{ 
string=$1 
array=([email protected]) 
echo "array is ${array[@]}" 
echo "array is ${array[1]}" 
return 
} 
array=(one two three) 
foo ${array[@]} 
colors=(red green blue) 
foo ${colors[@]} 
25

Bạn có thể chuyển mảng bằng cách tham chiếu đến một hàm trong bash 4.3+. Điều này có thể đến từ ksh, nhưng với một cú pháp khác. Ý tưởng chính là để thiết lập các thuộc tính -n:

show_value() # array index 
{ 
    local -n array=$1 
    local idx=$2 
    echo "${array[$idx]}" 
} 

này làm việc cho mảng lập chỉ mục:

$ shadock=(ga bu zo meu) 
$ show_value shadock 2 
zo 

Nó cũng làm việc cho mảng kết hợp:

$ days=([monday]=eggs [tuesday]=bread [sunday]=jam) 
$ show_value days sunday 
jam 

Xem thêm declare -n trong trang người đàn ông.

Các vấn đề liên quan