I am making a bash script and I have encountered a problem. So let's say I got this
我正在制作一个bash脚本,我遇到了一个问题。所以,假设我得到了这个
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?
我有什么方法可以做这个工作吗?我搜索了很多,没有找到任何工作。我认为使a []成为一个全局变量应该可以工作,但我找不到在我的代码中实际工作的东西。有没有办法将数组从函数返回到主程序?
Thanks in advance
提前致谢
3 个解决方案
#1
3
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:
这描述得很好。它在您的实际代码中不起作用的最可能原因是因为您碰巧在子shell中运行它:
cat textfile | create_some_array
echo ${a[*]}
would not work, because each element in a pipeline runs in a subshell, and
不起作用,因为管道中的每个元素都在子shell中运行,并且
myvalue=$(create_some_array)
echo ${a[*]}
would not work, since command expansion happens in a subshell.
不起作用,因为命令扩展发生在子shell中。
#2
2
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
#3
2
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:
更糟糕的是:如果你试图从外部“a”获得数组索引,那么它就是一个标量:
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:
尽管如此,printf似乎也没有帮助:
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...
P.S。:printf“%q”“$ {a [@]}”也可以正常工作......
#1
3
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:
这描述得很好。它在您的实际代码中不起作用的最可能原因是因为您碰巧在子shell中运行它:
cat textfile | create_some_array
echo ${a[*]}
would not work, because each element in a pipeline runs in a subshell, and
不起作用,因为管道中的每个元素都在子shell中运行,并且
myvalue=$(create_some_array)
echo ${a[*]}
would not work, since command expansion happens in a subshell.
不起作用,因为命令扩展发生在子shell中。
#2
2
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
#3
2
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:
更糟糕的是:如果你试图从外部“a”获得数组索引,那么它就是一个标量:
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:
尽管如此,printf似乎也没有帮助:
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...
P.S。:printf“%q”“$ {a [@]}”也可以正常工作......