This seems like a typical XY problem question ... So, all I can do to help is to highlight some points you mentioned and hopefully this will at least help you avoid dead ends and point you away from the wrong direction.
Hopefully, this will help you as well to see how many separate, focused, clear and individual questions are included in your single general question above so that in the future you might break them down and ask for each one separately if you wish.
First,
The option -n
is used to declare a reference variable nameref
and cannot be used to declare an array ... Please see the bash
builtin declare
... Please, see the demonstration below:
$ array=( "word1" "word2 space" "word3 *" )
# This will throw an error:
$ function my_func {
local -n my_array=( "$@" )
my_array+=("This" "That")
printf '%s\n' "${my_array[@]}"
}
$ my_func "${array[@]}"
bash: local: my_array: reference variable cannot be an array
word1
word2 space
word3 *
This
That
# This will not work:
$ function my_func {
local -n my_array="$1"
my_array+=("This" "That")
printf '%s\n' "${my_array[@]}"
}
$ my_func "${array[@]}"
This
That
You can, however, use a nameref
and pass the array/s names(not elements) as positional arguments, but this has its own disadvantage as well ... Because, you're not actually recreating the passed array/s as local array/s inside your function, but rather merely referencing the original array/s by another name and therefore changes are not "local to your function" as you might think ... Please, see the demonstration below:
$ array=( "word1" "word2 space" "word3 *" )
$ array2=( "word4" "word5" "word6" )
$ function my_func {
local -n my_array="$1"
local -n my_array2="$2"
my_array+=("This" "That")
my_array2+=("This2" "That2")
printf '%s\n' "${my_array[@]}"
printf '%s\n' "${my_array2[@]}"
}
# Run the function:
$ my_func "array" "array2"
word1
word2 space
word3 *
This
That
word4
word5
word6
This2
That2
# Run the same function again:
$ my_func "array" "array2"
word1
word2 space
word3 *
This
That
This
That
word4
word5
word6
This2
That2
This2
That2
# Print original arrays
$ echo "${array[@]}"
word1 word2 space word3 * This That This That
$ echo "${array2[@]}"
word4 word5 word6 This2 That2 This2 That2
Second,
Passing array elements as arguments to a function with my_func "${array[@]}"
will not pass them as an array but rather as positional arguments i.e. first element as $1
, second element as $2
... and so on ... Therefore you should rebuild the array inside the function with array=( "$@" )
... See the demonstration below:
$ array=( "word1" "word2 space" "word3 *" )
# This will work:
$ function my_func {
local my_array=( "$@" )
my_array+=("This" "That")
printf '%s\n' "${my_array[@]}"
}
$ my_func "${array[@]}"
word1
word2 space
word3 *
This
That
# This will not work:
$ function my_func {
local my_array=( "$1" )
my_array+=("This" "That")
printf '%s\n' "${my_array[@]}"
}
$ my_func "${array[@]}"
word1
This
That
Needless to say that if you pass more than one array to the function, they will be hard to split back into original separate arrays and they will be combined ... Please, see the demonstration below:
$ array=( "word1" "word2 space" "word3 *" )
$ array2=( "word4" "word5" "word6" )
$ function my_func {
local my_array=( "$@" )
my_array+=("This" "That")
printf '%s\n' "${my_array[@]}"
}
$ my_func "${array[@]}" "${array2[@]}"
word1
word2 space
word3 *
word4
word5
word6
This
That
Third,
You don't really need to handle an array in your script like this in order to make it available inside a function ... If an array(or variable) is defined in your script, then you can just call it directly inside your function like so:
$ array=( "word1" "word2 space" "word3 *" )
$ function my_func {
local my_array=( "${array[@]}" )
my_array+=("This" "That")
printf '%s\n' "${my_array[@]}"
}
$ my_func
word1
word2 space
word3 *
This
That
Fourth,
With proper quoting(as it should be in most cases), array expansion will pass each element as a single token ... Therefore you cant assign command options and their argument/s to an array element and expect it to work as usual in a command ... Please, see the demonstration below:
# This works:
$ echo -e 'new\nline'
new
line
# This doesn't:
$ array=( "-e 'new\nline'" )
$ echo "${array[@]}"
-e 'new\nline'
Fifth,
As for the warning message you see:
bash: warning: command substitution: ignored null byte in input.
That is actually the least of your problems ... It, however, simply means that you/your commands asked to include null byte/s(i.e. \0
from printf '%s\0' "${isufx[@]}"
in your function that you used in the command substitution) in/during a string creation/definition process(e.g. in the command substitution syntax) that will need its end to be identified in order to be handled properly later on ... and bash
can't do that as it actually uses C-style strings(which are terminated by a null character '\0') and therefor bash
ignores that and informs you about it ... So, simply change that and the message shouldn't appear anymore.