2015-10-04 4 views
1

Можно ли передать массив непосредственно функции в shell/bash, не сохраняя ее сначала переменной?Передача массива непосредственно в функцию в оболочке

В настоящее время пример:

function checkParameter(){ 
    param1=("${!1}") 
    for a in "${param1[@]}"; do 
     echo "${a}" 
    done 

    param2=("${!2}") 
    for b in "${param2[@]}"; do 
     echo "${b}" 
    done 
} 

a=("child 1 from 1" "child 2 from 1" "child 3 from 1") 
b=("child 1 from 2" "child 2 from 2") 
checkParameter a[@] b[@] 

Так я могу передать ("child 1 from 1" "child 2 from 1" "child 3 from 1") и ("child 1 from 2" "child 2 from 2") каким-то образом непосредственно к функции checkParameter, не сохраняя его в a и b в первую очередь?

привет и спасибо,
christopher2007

+1

Вы здесь * косвенно передаете «имя» этого массива функции, а затем расширяете ее для своих значений в функции. –

ответ

1

"$ 1" неизменна. Вот почему ваш пример должен хранить значение этого параметра во временной переменной. Это справедливо для [email protected] независимо от того, переданы ли они как массив или нет.

+0

так есть обходной путь? возможно, другой тип значения? ... sry, мой английский очень плохой, и поэтому я не могу понять сообщение, которое вы написали :( – christopher2007

0

Вы уверены, что вам нужно использовать массив?

checkparameters() { 
    for param in "[email protected]"; do 
     echo "$param" 
    done 
} 

checkparameters "a" "b" "c" 

Чтобы ответить на этот вопрос, я не думаю, что можно передать массив в качестве аргументов функционального направления без преобразований.

EDIT

Вы могли бы попробовать что-то вроде:

[ ~]$ cat test.sh 
#!/bin/bash 

declare -a a1 
a1=("a" "b") 

declare -a a2 
a2=("c" "d") 

checkParameters(){ 
    for i in "[email protected]"; do 
     echo "Content of $i :" 
     for j in $(eval "echo \${$(echo $i)[@]}"); do 
      echo $j 
     done 
    done 
} 

checkParameters "a1" "a2" 
[ ~]$ ./test.sh 
Content of a1 : 
a 
b 
Content of a2 : 
c 
d 
+0

да, потому что в оригинале я должен передать две отдельные массивы с разной динамической длиной в функцию. Я изменил свой вопрос с лучшим примером для этого. Извините за попытку сохранить первый пример настолько коротким, что этого было невозможно увидеть. – christopher2007

+0

@ christopher2007 Я обновил свой ответ;) –

+0

спасибо за ваши усилия, но у меня много вызовов функций например, в конструкции if/elif/elif /.../ elif/else, и я не могу определить новые массивы между ними. это что-то вроде 'if [checkParameters" a1 "" b1 "] ... elif [checkParameters" a2 "" b2 "] ... elif [checkParameters" a3 "" b3 "] ...' и поэтому мне нужно определите все эти массивы ПЕРЕД первым «если», и чтобы этого избежать, я надеялся, что я сразу вызову функцию с массивами ... – christopher2007

0

В общем, вы не передавать массивы в Bash сценарии или функции как массивы:

Когда вы передаете массив в командной строке, например, "${ary[@]}", вы не передаете arra y, но его Элементы as Отдельные показатели; первый элемент массива связан специальный параметр $1, второй $2, ...

Попытка решения использует умный обходной путь, передавая имени массива переменных функции, где переменная косвенность (${!...}) используется для доступа к массиву внутри функции. [1]

По определению, этот подход требует, чтобы массивы быть сохранены в переменных фронт.

Что касается Вашего желания сделать это без сохранения ваших массивов в переменной: Вы не можете передать массиву литералов в качестве аргументов в Bash; концептуальный эквивалент которого составляет , просто пройдите отдельных параметров.

Проблема в том, что вы не сможете определить, где находятся элементы одного массива, а следующий начинается.

Вы можете обратиться к этому, введя параметр separator, единственная цель которого - указать, когда заканчивается массив.

Например, если вы знаете, что ваши элементы не содержат новой строки, вы можете использовать $\n в качестве разделителя:

#!/usr/bin/env bash 

function checkParameter(){ 
    local -i arrayNdx=1 
    for param; do # Loop over all parameters 
    [[ $param == $'\n' ]] && { ((++arrayNdx)); continue; } 
    echo "From array $arrayNdx: [$param]" 
    done 
} 

# Pass the array elements as individual parameters 
# and use $'\n' (a newline) to separate the elements of the 1st 
# array from those of the 2nd. 
checkParameter "a1-child 1" "a1-child 2" "a1-child 3" $'\n' "a2-child 1" "a2-child 2" 

[1] Просто, чтобы показать упрощенную версию вашего решение сделать переменной косвенность часть понятнее:

function checkParameter(){ 
    for a in "${!1}"; do 
     echo "${a}" 
    done 

    for b in "${!2}"; do 
     echo "${b}" 
    done 
} 

checkParameter a[@] b[@] 

Смежные вопросы