从Bash函数返回数组

时间:2013-02-12 18:24:42

标签: arrays bash function shell return-value

我正在制作一个bash脚本,但我遇到了一个问题。所以,让我说我得到了这个

function create_some_array(){
  for i in 0 1 2 3 .. 10
  do
    a[i]=$i
  done
}

create_some_array
echo ${a[*]}

有什么方法可以让我的工作吗?我搜索了很多,没有找到任何工作。 我认为使a[]成为一个全局变量应该可以工作,但我找不到在我的代码中实际工作的东西。有没有办法将数组从函数返回到主程序?

提前致谢

5 个答案:

答案 0 :(得分:3)

如所描述的那样工作正常。最可能的原因是它在您的实际代码中不起作用是因为您碰巧在子shell中运行它:

cat textfile | create_some_array
echo ${a[*]}

不起作用,因为管道中的每个元素都在子shell中运行,而

myvalue=$(create_some_array)
echo ${a[*]}

不起作用,因为命令扩展发生在子shell中。

答案 1 :(得分:2)

您可以为函数创建一个本地数组,然后将其返回:

function create_some_array(){
    local -a a=()
    for i in $(seq $1 $2); do
        a[i]=$i
    done
    echo ${a[@]}
}

declare -a a=()

a=$(create_some_array 0 10)

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

答案 2 :(得分:2)

当数组中有空格时,这不会像预期的那样工作:

function create_some_array() {
    local -a a=()
    for i in $(seq $1 $2); do
        a[i]="$i $[$i*$i]"
    done
    echo ${a[@]}
}

更糟糕的是:如果你试图从外部得到数组索引" a",它结果是一个标量:

echo ${!a[@]}

即使作为数组赋值也不会有帮助,因为回声线自然会删除引用,并且无法操纵评估顺序以逃避引用:尝试

function create_some_array() {
...
    echo "${a[@]}"
}

a=($(create_some_array 0 10))
echo ${!a[@]}

但是,printf似乎也没有帮助:

function create_some_array() {
...
    printf " \"%s\"" "${a[@]}"
}

一方面似乎产生了正确的输出:

$ create_some_array 0 3; echo
 "0 0" "1 1" "2 4" "3 9"

但是作业并不适用于另一个:

$ b=($(create_some_array 0 3))
$ echo ${!b[@]}
0 1 2 3 4 5 6 7

所以我的最后一招是做如下的作业:

$ eval b=("$(create_some_array 0 3)")
$ echo -e "${!b[@]}\n${b[3]}"
0 1 2 3
3 9

TATAAA!

P.S。:printf"%q" " $ {A [@]}"也行得很好......

答案 3 :(得分:0)

嗨,这是我的解决方法:

show(){
    local array=()
    array+=("hi")
    array+=("everything")
    array+=("well?")
    echo "${array[@]}"
}

for e in $(show);do
    echo $e
done

在以下位置尝试此代码:https://www.tutorialspoint.com/execute_bash_online.php

答案 4 :(得分:0)

这两种方法都适用于 shbash

arr1=("192.168.3.4" "192.168.3.4" "192.168.3.3")

strArr=$(removeDupes arr1) # strArr is a string
for item in $strArr; do arr2+=("$item"); done # convert it to an array
len2=${#arr2[@]} # get array length
echo "${len2}" # echo length

eval arr3=("$(removeDupes arr1)") # shellcheck does not like this line and won't suppress it but it works
len3=${#arr3[@]} # get array length
echo "${len3}" # echo length

顺便说一句,removeDupes 函数如下所示:

removeDupes() {
  arg="$1[@]"
  arr=("${!arg}")
  len=${#arr[@]}
  resultArr=()
  # some array manipulation here
  echo "${resultArr[@]}"
}

此答案基于但更好地解释和简化了@Hans 和@didierc 的答案