2

I am working on an embedded linux. I want to write a bash script that automatically fixes partitions.

I have declared an associative array where the key is the mount point and the value is the device to be mounted.

Now, my problem is that the devices may have different filesystems and the right version of fsck should be selected.

Each filesystem has its own fsck variant, such as fsck.vfat and fsck.ext4.

I need to somehow bring this in the loop so the right variant is being called. Sadly the main variant fsck does not provide a automatic fix or detection of filesystems in my configuration.

So the real question is how to have a lookup table here?

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
5
  • Does mount show the fs type?
    – choroba
    Mar 4 at 10:17
  • @choroba Yes it does. Altenatively I could parse the mount result and find out the right command, but that would be rather complex... I was hoping that there is a built-in solution in bash
    – DEKKER
    Mar 4 at 10:32
  • @DEKKER the built-in solution is to have fsck autodetect the filesystem and use the right tool itself, but that doesn't seem to work for you
    – muru
    Mar 4 at 10:47
  • The command blkid will show you all connected blockdevices and the used filesystems. Not every filesystem has a separate fsck command, for example BTRFS has only a dummy which does nothing. Also, you should know that fsck for many filesystems can be a destructive command which is able to destroy data if not handled with care. So you should better look for options that your filesystems won't become corrupt in the first place. fsck only guarantees to repair a corrupt filesystem, not the stored files/data, which means, if the filesystem is corrupted by a file, fsck will remove it.
    – paladin
    Mar 4 at 11:30
  • For embedded Linux I recommend using a read-only filesystem which uses an overlay-FS.
    – paladin
    Mar 4 at 11:33

2 Answers 2

3

You can get the filesystem type from lsblk. For example, on my machine:

$ 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

So, with that in mind, you can do something like this (I need to post-process to add a value where there is none in order for the data to be correct):

#!/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
1
  • nice! I thought lsblk would just read the partition type, not investigate the data (I would guess it uses the relatively new fsinfo syscall)! Mar 4 at 19:43
2

Bash can't guess filesystem types. And you can't really ask mount itself, because I suspect the whole point of checking is also covering cases where things are slightly broken and a filesystem can't be mounted automatically.

So, short of installing a fully-fledged fsck that can detect filesystems itself (or using / abusing file itself), you need to feed in that info yourself. Shouldn't really be a problem, since you're already manually defining the block devices and their mount points, anyways! (Which makes one wonder why you're not simply relying on /etc/fstab and run fsck -A.)

You could integrate your knowledge of the file system into your associative array:

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
)

And extract that in your iteration:

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

(I renamed your $part to $mountpoint, because part is really misleading; that's a mount point, not a partition.)

You could do something like mount -t "${type}" and extract the type from the fsck.TYPE string, if present, and simply don't mount if not present.

1
  • Why is detecting the fs type difficult? You don't need the disk to be mounted for that and various tools report the file type of partitions (e.g. lsblk, parted, fdisk, blkid off the top of my head).
    – terdon
    Mar 4 at 12:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .