击;创建从其他变量计算名称的数组

时间:2017-08-07 09:53:14

标签: arrays bash for-loop

我的目标是为/sys/block;

中列出的每个块设备创建一个分区列表
#!/bin/bash
block_devices_list=($(ls /sys/block))
partition_list=($(cat /proc/partitions | awk '{print $4}'))
unset partition_list[0]

for block_device in ${block_devices_list[@]}; do
    for partition in ${partition_list[@]}; do
        partitions+=($(echo $partition | grep $block_device))
    done
    # Right here?
    unset partitions
done

每次外部'for loop'完成它的循环时,它最终会得到一个特定块设备的分区数组。此时我想将数据传输到一个单独的数组,以它所属的设备动态命名(例如'partitions_sda')。

我已经阅读了一些关于'动态'变量名称,'关联'数组等等的问题/答案,但似乎无法解决这个问题。任何帮助非常感谢。

3 个答案:

答案 0 :(得分:0)

不确定我理解你要做什么,但这是一个你可以开始的例子:

#!/bin/bash
list1=(a b c)
list2=(j k l)
for x in ${list1[@]}; do
    for y in ${list2[@]}; do
        tmplist+=(${x}${y})
    done
    cmd="declare -a list_${x}=(${tmplist[@]})"
    eval $cmd
    unset tmplist
done
echo "list_a: ${list_a[@]}"
echo "list_b: ${list_b[@]}"
echo "list_c: ${list_c[@]}"

它显示了如何创建从其他变量计算名称的数组,如何取消设置临时数组...

答案 1 :(得分:0)

我会创建两种类型的数组。一个用于包含磁盘名称,然后是每个磁盘的不同数组,用于存储分区特定信息。

#!/usr/bin/env bash                                                                                                                                   
while read -r l; do
    t="${l#* }"
    if [[ $t == "disk" ]]; then
        # disks list contains all the disk names
        disks+="${l% *} "
    elif [[ $t == "part" ]]; then
        # for each disk 'XXX', a separate partitions array 'parts_XXX' is created
        [[ $l =~ [^a-z0-9]*([a-z]*)([0-9]*)\  ]] && d="${BASH_REMATCH[1]}" && p="${BASH_REMATCH[2]}"
        eval parts_$d+=\"my-value=\$d\$p \" # append to partitians array
    else
        echo "unknown type $t in $l"
        exit 1
    fi  
done <<< $(lsblk -n --output=NAME,TYPE | tr -s ' ')

# arrays are created. now iterate them
for i in ${disks[@]}; do
    echo "iterating partitions of disk: $i"
    # following is the name of the current disks partitions array
    var=parts_$i[@]
    # iterate partitians array of the current disk
    for j in ${!var}; do
        echo ">> $j"
    done
done

答案 2 :(得分:0)

作为最佳实践示例(适用于bash 4.3或更新版本):

#!/bin/bash

for blockdev in /sys/block/*; do
  devname=${blockdev##*/}               # remove leading path elements
  devname=${devname//-/_}               # rename dashes in device name to underscores
  declare -a "partitions_${devname}=()" # define an empty array
  declare -n _current_partitions="partitions_$devname"        # define a nameref
  for part in "$blockdev"/*/dev; do   # iterate over partitions
    [[ -e $part ]] || continue                                # skip if no matches
    part=${part%/dev}                                         # strip trailing /dev
    _current_partitions+=( "${part##*/}" )                    # add match via nameref
  done
  unset -n _current_partitions          # clear the nameref
  declare -p "partitions_$devname"      # print our resulting array
done

对于我的本地测试VM,这会发出:

declare -a partitions_dm_0=()
declare -a partitions_dm_1=()
declare -a partitions_sda=([0]="sda1" [1]="sda2")
declare -a partitions_sdb=()
declare -a partitions_sr0=()

...这是正确的,因为sda是唯一的分区设备。

此处的基本机制是namerefdeclare -n name1=name2将允许人们在名称name2下引用变量name1,包括更新或分配,直到{{ 1}}已执行。