如何生成查找表或数据结构并在 Bash 中对其执行循环

如何生成查找表或数据结构并在 Bash 中对其执行循环

我正在开发嵌入式Linux。我想写一个自动修复分区的bash脚本。

我声明了一个关联数组,其中键是安装点,值是要安装的设备。

现在,我的问题是设备可能有不同的文件系统,fsck应该选择正确的版本。

每个文件系统都有自己的fsck变体,例如fsck.vfatfsck.ext4

我需要以某种方式将其带入循环中,以便调用正确的变体。遗憾的是,主要变体fsck没有在我的配置中提供文件系统的自动修复或检测。

所以真正的问题是如何在这里有一个查找表?

declare -A arrPartitionsToCheck=(
[/run/media/my-backup]="/dev/sda1" # vfat
[/run/media/my-data]="/dev/sdb1"   # ext4
)

for part in "${!arrPartitionsToCheck[@]}"; do

    # Unmount
    # umount /dev/sda1
    umount "${arrPartitionsToCheck[$part]}"

    # Select the right variant of FSCK and repair automatically
    fsck.vfat -a "${arrPartitionsToCheck[$part]}"

    # Mont Again! For example
    # mount /dev/sda1 /run/media/my-backups
    mount "${arrPartitionsToCheck[$part]}" "$part"    

done

答案1

您可以从 获取文件系统类型lsblk。例如,在我的机器上:

$ lsblk -o PATH,FSTYPE
PATH             FSTYPE
/dev/mapper/home ext4
/dev/nvme0n1     
/dev/nvme0n1p1   vfat
/dev/nvme0n1p2   
/dev/nvme0n1p3   BitLocker
/dev/nvme0n1p4   ntfs
/dev/nvme0n1p5   ext4
/dev/nvme0n1p6   crypto_LUKS
/dev/nvme0n1p7   swap

因此,考虑到这一点,您可以执行类似的操作(我需要进行后处理以在没有值的情况下添加一个值,以使数据正确):

#!/bin/bash

declare -A arrPartitionsToCheck=(
  [/run/media/my-backup]="/dev/sda1" # vfat
  [/run/media/my-data]="/dev/sdb1"   # ext4
)

## store the file system types
declare -A fileSystems="( $(lsblk -o PATH,FSTYPE | awk 'NF==1{$2="."}1' ) )"

for part in "${!arrPartitionsToCheck[@]}"; do

  device=${arrPartitionsToCheck[$part]}
  fstype=${fileSystems[$device]}

  # Unmount
  # umount /dev/sda1
  umount "${arrPartitionsToCheck[$part]}"
  
  # Select the right variant of FSCK and repair automatically
  fsck."$fstype" -a "${arrPartitionsToCheck[$part]}"
  
  # Mont Again! For example
  # mount /dev/sda1 /run/media/my-backups
  mount "${arrPartitionsToCheck[$part]}" "$part"    

done

答案2

Bash 无法猜测文件系统类型。而且你不能真正询问 mount 本身,因为我怀疑检查的全部目的还包括事情稍微损坏并且文件系统无法自动安装的情况。

fsck因此,如果没有安装一个可以检测文件系统本身(或使用/滥用自身)的成熟的文件系统file,您需要自己输入该信息。无论如何,这实际上不应该成为问题,因为您已经手动定义了块设备及其安装点! (这让人想知道为什么你不简单地依赖/etc/fstab并运行fsck -A。)

您可以将对文件系统的了解集成到关联数组中:

declare -A arrPartitionsToCheck=(
[/run/media/my-backup]="fsck.vfat:/dev/sda1"
[/run/media/my-data]="fsck.ext4:/dev/sdb1"
[swap]="true:/dev/sdb9" #swap, don't check
)

并在迭代中提取它:

for mountpoint in "${!arrPartitionsToCheck[@]}"; do
    spec="${arrPartitionsToCheck[$mountpoint]}"
    tool="${spec%:*}"
    device="${spec#*:}"
    # Unmount
    # umount /dev/sda1
    umount "${device}"

    # Select the right variant of FSCK and repair automatically
    "${tool}" -a "${device}"

    # Mount Again! For example
    # mount /dev/sda1 /run/media/my-backups
    mount "${device}" "${mountpoint}"
done

(我将您的重命名$part$mountpoint,因为part这确实具有误导性;那是挂载点,而不是分区。)

您可以执行类似操作mount -t "${type}",从字符串中提取类型fsck.TYPE(如果存在),如果不存在则不安装。

相关内容