代码之家  ›  专栏  ›  技术社区  ›  kbs

Bash-使用函数修改数组

  •  0
  • kbs  · 技术社区  · 8 年前

    我不明白为什么这个示例脚本不修改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说:

    ^--SC2034:array1显示为未使用。验证使用(或导出,如果外部使用)。 没有道理,我显然在用它:

    modify_array2 array1[@] array2[@]
    

    第11行: _array2[“$index”]=“$i” ^--SC2034:\u array2显示为未使用。验证使用(或导出,如果外部使用)。

    修改array2 array1[@]array2[@]
    

    以及在函数中使用:

    _array2["$index"]="$i"
    

    printf“$i\n” ^--SC2059:不要在printf格式字符串中使用变量。使用printf“..%s…”“$foo”。

    好吧,但我也试过回声,结果一样

    1 回复  |  直到 8 年前
        1
  •  2
  •   Néstor Lucas Martínez    8 年前

    我看到你的剧本有两个问题。第一个是你的内心 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 创建两个局部变量。这只是我个人的爱好 声明 地方的 (见 help declare ).

    在建议的解决方案中,函数被称为传递数组本身(而不是数组的值)。在函数内部,创建了两个局部变量,作为对作为参数传递给函数的数组的引用。这就是 -n 选项意味着:创建 姓名参考 (引用)另一个变量。如果你在Bash手册页上查找 姓名参考 你会看到的” 在shell函数中,通常使用nameref来引用一个变量,该变量的名称作为参数传递给函数 ". 这样,对引用所做的任何赋值都被视为对作为参数传递的变量的赋值。

    推荐文章