Cómo pasar matriz como argumento para una función en Bash

Como sabemos, en la progtwigción de bash, la forma de pasar los argumentos es $1 , …, $N Sin embargo, no me resultó fácil pasar una matriz como argumento a una función que recibe más de un argumento. Aquí hay un ejemplo:

 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 

Como se describió, la función f recibe dos argumentos: el primero se asigna a x que es una matriz, el segundo a y .

f puede ser llamado de dos maneras. La primera forma usa "${a[@]}" como primer argumento, y el resultado es:

 jfaldsj jflajds 

La segunda forma usa "${a[*]}" como primer argumento, y el resultado es:

 jfaldsj jflajds LAST 

Ninguno de los resultados es como yo deseaba. Entonces, ¿alguien tiene alguna idea sobre cómo pasar array entre las funciones correctamente?

No puede pasar una matriz, solo puede pasar sus elementos (es decir, la matriz expandida).

 #! /bin/bash function f() { a=("$@") ((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" 

La otra posibilidad sería pasar la matriz por su nombre:

 #! /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' fx "$b" 

Puede pasar una matriz por referencia a una función en bash 4.3+. Esto proviene probablemente de ksh, pero con una syntax diferente. La idea clave es establecer el atributo -n:

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

Esto funciona para matrices indexadas:

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

También funciona para matrices asociativas:

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

Ver también declare -n en la página man.

Puede pasar el valor “escalar” primero. Eso simplificaría las cosas:

 f(){ b=$1 shift a=("$@") for i in "${a[@]}" do echo $i done .... } a=("jfaldsj jflajds" "LAST") b=NOEFLDJF f "$b" "${a[@]}" 

En este punto, también podría usar los parámetros posicionales array-ish directamente

 f(){ b=$1 shift for i in "$@" # or simply "for i; do" do echo $i done .... } f "$b" "${a[@]}" 

Esto resolverá el problema de pasar array a la función:

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