我不明白为什么这个示例脚本不修改array2的内容。似乎我们应该能够通过遍历array1的元素并通过array2的索引将对应的元素设置为等于array1中的元素来将array2设置为等于array1
#!/bin/bash
array1=(1 2 3)
array2=()
modify_array2 () {
#set array2 to be equal to array1 by iterating through array1's
#elements and setting the corresponding element by index of array2 by
#to be equal to the element in array1
index=0
declare -a _array1=("${!1}")
declare -a _array2=("${!2}")
for i in "${_array1[@]}"; do
_array2["$index"]="$i"
((index++))
done
}
modify_array2 array1[@] array2[@]
#this should permanently modify array2, however if we print the
#contents of array2, we get nothing:
for i in "${array2[@]}"; do
printf "$i\n"
done
输出:
Shellcheck表示以下内容:
第3行: array1 =(1 2 3) ^-SC2034:array1似乎未使用。验证使用情况(或在外部使用时导出)。 没道理,我很明显在以下地方使用它:
modify_array2 array1[@] array2[@]
第11行: _array2 [“ $ index”] =“ $ i” ^-SC2034:_array2似乎未使用。验证使用情况(或在外部使用时导出)。
奇数,因为我不是通过在以下位置使用位置参数进行扩展来使用它的:
modify_array2 array1[@] array2[@]
并在函数中使用:
_array2["$index"]="$i"
第19行: printf“ $ i \ n” ^-SC2059:不要在printf格式字符串中使用变量。使用printf“ ..%s ..”“ $ foo”。
很好,但我也尝试了echo,同样的结果
答案 0 :(得分:2)
我看到您的脚本有两个问题。第一个是在modify_array2
函数内部,您使用了两个声明的局部变量,它们是由作为参数传递的值创建的。第二个是永远不要修改array2
变量。
可能的解决方案是:
#!/bin/bash
array1=(1 2 3)
array2=()
modify_array2 () {
#set array2 to be equal to array1 by iterating through array1's
#elements and setting the corresponding element by index of array2 by
#to be equal to the element in array1
index=0
local -n _array1=$1
local -n _array2=$2
for i in "${_array1[@]}"; do
_array2["$index"]="$i"
((index++))
done
}
printf "These are the contents of array1 before calling the function:\n"
printf "%s\n" "${array1[@]}"
printf "These are the contents of array2 before calling the function:\n"
printf "%s\n" "${array2[@]}"
modify_array2 array1 array2
printf "These are the contents of array2 after calling the function:\n"
printf "%s\n" "${array2[@]}"
我使用declare
而不是local
来创建两个局部变量。这只是我的个人喜好,因为declare
使变量在函数中使用时就像在local
中创建变量一样(请参阅help declare
)。
但是与这个问题最相关的是处理传递给函数的参数的方式。在原始脚本中,它们是按值传递的。因此,不可能对参数列表中传递的第二个数组进行任何更改。
在提出的解决方案中,该函数称为传递数组本身(而不是其值)。在函数内部,将创建两个局部变量,作为对作为参数传递给函数的数组的引用。这就是-n
选项的含义:为另一个变量创建一个 nameref (引用)。如果您在Bash手册页中查找 nameref ,您会看到“ shell函数中通常使用nameref来引用一个变量,该变量的名称作为参数传递给该函数”。这样,您对引用所做的任何赋值都将被视为对作为参数传递的变量的赋值。