如何在 Bash 中迭代关联数组(其中值是数组)?

Jer*_*ska 1 arrays bash for-loop associative-array

我编写此代码是为了循环访问 LAN 上的用户名和域。遗憾的是,脚本没有打印任何内容。

#!/bin/bash

construct_array_of_trgts() {
  declare -A usrs_n_dmns
  
  local -a guest_dmns
  local -a usrs=("j" "jim" "o" "root")
  local -a guest_dmns=("raspberrypi" "lenovo")
  for d in "${guest_dmns[@]}"; do 
    PS3="Select the users to include for sshing into $d. Q when done selecting."$'\n'
    local -a targt_usrs
    select u in "${usrs[@]}"; do
      if [[ "$u" ]]; then
        targt_usrs+=("$u")
     elif [[ "$REPLY" == 'q' ]]; then 
      break;
     fi
    done
    usrs_n_dmns["${d}"]="$targt_usrs"
  done
  
}
construct_array_of_trgts

for d in "${!usrs_n_dmns[@]}"; do
  targt_usrs=("${usrs_n_dmns["${d}"]}")
  echo "$usrs_n_dmns"
  for u in "${targt_usrs[@]}"; do
    echo "ssh ${u}@${d}" 
  done
done
Run Code Online (Sandbox Code Playgroud)

为什么这个脚本不打印任何可见的东西?数组是否有可能成为 Bash 中关联数组中的值?

Léa*_*ris 6

正如 @KamilCuk 所解释的,Bash 中没有嵌套或多维数组。

Bash 数组只能存储标量或整数值。

不过,可以将整个数组作为单独引用的元素的空格分隔串联传递,这些元素适合在 Bashdeclare语句中按原样重用。

  1. 为了引用值,Bash 版本 4.4+ 提供了@Q扩展参数。
  2. 要将数组元素连接到单个字符串中,每个元素都以空格分隔,它需要*作为数组扩展,例如${array[*]}.

值引用参数和数组到字符串连接都可以组合成单个扩展,例如:${array[*]@Q}

例如:

#!/usr/bin/env bash

declare -a array=(foo bar 'Hello World')

printf '(%s)\n' "${array[*]@Q}"
Run Code Online (Sandbox Code Playgroud)

修复了您的代码,现在它可以工作了:

#!/usr/bin/env bash

construct_array_of_trgts() {
  local -a usrs=("j" "jim" "o" "root")
  local -a guest_dmns=("raspberrypi" "lenovo")
  for d in "${guest_dmns[@]}"; do
    PS3="Select the users to include for sshing into $d. Q when done selecting."$'\n'
    local -a targt_usrs=()
    while :; do
      select u in "${usrs[@]}"; do
        if [[ "$u" ]]; then
          targt_usrs+=("$u")
        elif [[ "$REPLY" == 'q' ]]; then
          break 2
        fi
      done
    done
    # Array to scalar of space-delimited quoted values
    usrs_n_dmns["${d}"]="${targt_usrs[*]@Q}"
  done
}

declare -A usrs_n_dmns

construct_array_of_trgts

for d in "${!usrs_n_dmns[@]}"; do
  # Scalar value is expanded into array delcare
  declare -a targt_usrs="(${usrs_n_dmns[$d]})"
  for u in "${targt_usrs[@]}"; do
    echo ssh "${u}@${d}"
  done
done
Run Code Online (Sandbox Code Playgroud)


Kam*_*Cuk 5

如何在 Bash 中迭代关联数组(其中值是数组)?

这是不可能的,因为关联数组值不能是数组。

为什么这个脚本不打印任何可见的内容?

construct_array_of_trgts() {
  declare -A usrs_n_dmns
Run Code Online (Sandbox Code Playgroud)

declare在函数体内等于local. 变量usrs_n_dmns在函数localconstruct_array_of_trgts。返回后construct_array_of_trgtsusrs_n_dmns已不复存在。

如果您希望该变量是全局变量,请添加-gdeclare.

数组是否有可能成为 Bash 中关联数组中的值?

不。