I am making a bash script and I have encountered a problem. So let's say I got this
function create_some_array(){
for i in 0 1 2 3 .. 10
do
a[i]=$i
done
}
create_some_array
echo ${a[*]}
Is there any way I can make this work? I have searched quite a lot and nothing I found worked.
I think making the a[]
a global variable should work but I can't find something that actually works in my code. Is there any way to return the array from the function to main program?
Thanks in advance
A bash function can return a value via its exit status after execution. By default, a function returns the exit code from the last executed command inside the function. It will stop the function execution once it is called. You can use the return builtin command to return an arbitrary number instead.
Print Bash Array We can use the keyword 'declare' with a '-p' option to print all the elements of a Bash Array with all the indexes and details. The syntax to print the Bash Array can be defined as: declare -p ARRAY_NAME.
Example: Bash function returns multiple values, passed via command substitution, with a READ command and Here string in calling script #bash #bash_exemplar · GitHub.
This won't work as expected when there are whitespaces in the arrays:
function create_some_array() {
local -a a=()
for i in $(seq $1 $2); do
a[i]="$i $[$i*$i]"
done
echo ${a[@]}
}
and worse: if you try to get array indices from the outside "a", it turns out to be a scalar:
echo ${!a[@]}
even assignment as an array wont help, as possible quoting is naturally removed by the echo line and evaluation order cannot be manipulated to escape quoting: try
function create_some_array() {
...
echo "${a[@]}"
}
a=($(create_some_array 0 10))
echo ${!a[@]}
Still, printf seems not to help either:
function create_some_array() {
...
printf " \"%s\"" "${a[@]}"
}
seems to produce correct output on one hand:
$ create_some_array 0 3; echo
"0 0" "1 1" "2 4" "3 9"
but assignment doesn't work on the other:
$ b=($(create_some_array 0 3))
$ echo ${!b[@]}
0 1 2 3 4 5 6 7
So my last trick was to do assignment as follows:
$ 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[@]}" also works fine...
This works fine as described. The most likely reason it doesn't work in your actual code is because you happen to run it in a subshell:
cat textfile | create_some_array
echo ${a[*]}
would not work, because each element in a pipeline runs in a subshell, and
myvalue=$(create_some_array)
echo ${a[*]}
would not work, since command expansion happens in a subshell.
You can make an array local to a function, and then return it:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With