First I've read about passing arrays in general -- all examples I saw first created temporary variable for array and then passed it. Taken from https://stackoverflow.com/a/26443029/210342
show_value () # array index
{
local -n myarray=$1
local idx=$2
echo "${myarray[$idx]}"
}
shadock=(ga bu zo meu)
show_value shadock 2
Is there a way to pass array directly as literal, i.e. without creating temporary variable?
I tried naive approach simply substituting the name with data, but I syntax error on "(".
Update:
I use openSUSE Leap 15.3 with bash 4.4. The above code of course works, but I would like to change the call into:
show_value (ga bu zo meu) 2
i.e. pass array data directly (without using extra variable).
CodePudding user response:
If you want to change the order of the arguments:
show_value () # index array_element [...]
{
local idx=$1
local -a myarray=("${@:2}")
echo "${myarray[$idx]}"
}
then
shadock=(ga bu zo meu)
show_value 2 "${shadock[@]}" # => zo
If you want to keep the index as the last argument, then
show_value () # array_element [...] index
{
local -a myarray=("${@:1:$#-1}")
local idx=${!#}
echo "${myarray[$idx]}"
}
show_value "${shadock[@]}" 2 # => zo
local -n myarray=$1
is certainly much tidier than all that, isn't it? It will also be faster and more memory efficient -- you don't have to copy all the data.
CodePudding user response:
Function arguments are not structured enough to handle nested data structures like arrays. Arguments are a flat list of strings, that's it.
You can expand the array inline:
show_value "${shadock[@]}" 2
However the delimiters are lost. There's no way to know where the array starts and end since it expands to:
show_value ga bu zo meu 2
You'll have to figure out the array bounds yourself. Options include:
If the command has only a single array parameter, make it the last one. This is what many traditional UNIX tools that take multiple file names do. Examples:
ls <file>...
,chmod <mode> <file>...
.You can put the array in the middle if there's a fixed number of arguments preceding/following it such that you can unambiguously determine where the array is. Example:
cp <file>... <dir>
.If you have multiple arrays, you can ask users to separate them with
--
. Many of git's more complicated subcommands do this.
I'd caution against taking an array name as an argument. That's a very shell-specific technique. It would make it hard to turn the function into a full-fledged script or binary down the road.
CodePudding user response:
Can you consider this syntax :
show_value () # array index
{
local -a myarray=$1
local idx=$2
echo "${myarray[$idx]}"
}
show_value "(ga bu zo meu)" 2
For security reasons, you need to be sure of the contents of the array you pass into the function.