Reputation: 1517
is it possible to pass an array directly to a function in shell/bash, without saving it first to a variable?
currently example:
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[@]
So can I pass the ( "child 1 from 1" "child 2 from 1" "child 3 from 1" )
and the ( "child 1 from 2" "child 2 from 2")
somehow directly to the function checkParameter
, without saving it in a
and b
first?
greetings and thanks,
christopher2007
Upvotes: 1
Views: 103
Reputation: 437111
Generally, you cannot pass arrays to Bash scripts or functions as arrays:
When you pass an array on the command line, e.g., "${ary[@]}"
, you're not passing an array, but its elements as individual parameters; the first array element is bound to special parameter $1
, the second to $2
, ...
Your solution attempt employs a clever workaround by passing the name of array variables to the function, where variable indirection (${!...}
) is used to access the array inside the function.[1]
By definition, this approach requires the arrays to be stored in variables up front.
As for your desire to do it without storing your arrays in a variable: You cannot pass array literals as arguments in Bash; the conceptual equivalent of that is to simply pass individual parameters.
The problem with that is that you won't be able to tell where the elements of one array end and the next one begins.
You can address that by introducing a separator parameter whose sole purpose is to indicate when an array ends.
For instance, if you know that your elements never contain a newline, you can use $\n
as the separator:
#!/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] Just to show a simplified version of your solution to make the variable-indirection part clearer:
function checkParameter(){
for a in "${!1}"; do
echo "${a}"
done
for b in "${!2}"; do
echo "${b}"
done
}
checkParameter a[@] b[@]
Upvotes: 0
Reputation: 3838
Are you sure that you need to use an array ?
checkparameters() {
for param in "$@"; do
echo "$param"
done
}
checkparameters "a" "b" "c"
To answer the question, I don't think that is possible to pass an array as function's args without transformations.
EDIT
You could try something like :
[ ~]$ cat test.sh
#!/bin/bash
declare -a a1
a1=("a" "b")
declare -a a2
a2=("c" "d")
checkParameters(){
for i in "$@"; 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
Upvotes: 0
Reputation:
"$1" is immutable. That is why your example has to store the value of it in a temporary variable. This holds true for $@
regardless of whether they are passed as an array or not.
Upvotes: 1