cClaude.rocks ☕ Le blog

[Nouvelles technologies du libre, sciences et coups de gueule…]

Menu
đŸ˜€ Ce billet a Ă©tĂ© Ă©ditĂ© le : 2024-08-20

Monter au niveau du systÚme un disque dur, une clé USB
 peu sembler assez difficile sous Linux.

Une commande vient à votre secours : blkid (“Block Identifier”)

Elle permet d’afficher les attributs des partitions (Une partition est vue par Linux comme un pĂ©riphĂ©rique de bloc, d’oĂč le nom).


ඏ

Présentation de « blkid »

Voici ce que peut retourner la commande blkid

blkid
/dev/mmcblk0p1: LABEL_FATBOOT="boot" LABEL="boot" UUID="5DE4-665C" TYPE="vfat" PARTUUID="eac47f08-01"
/dev/mmcblk0p2: LABEL="rootfs" UUID="729c5bb3-bcb2-4267-9ca0-09ef59e10bf0" TYPE="ext4" PARTUUID="eac47f08-02"

On constate que toutes les informations requises au montage d’une partition sont prĂ©sentes, Ă  part bien Ă©videment le chemin vers le point de montage.

L’option --output ou -o permet de modifier le format de sortie :

blkid -o export

On a alors quelque chose comme ça :

DEVNAME=/dev/mmcblk0p1
LABEL_FATBOOT=boot
LABEL=boot
UUID=5DE4-665C
TYPE=vfat
PARTUUID=eac47f08-01

DEVNAME=/dev/mmcblk0p2
LABEL=rootfs
UUID=729c5bb3-bcb2-4267-9ca0-09ef59e10bf0
TYPE=ext4
PARTUUID=eac47f08-02

ඏ

Conversion de la sortie de « blkid » en JSON

( echo '[{' ; blkid -o export ; echo '}]' ) |
  sed -E -e 's|^([A-Z_]+)=(.*)$|"\1": "\2",|g' -e 's|^$|},{|g' |
  tr -d '\n' |
  sed -e 's|,}|}|g' -e 's,\\ , ,g' |
  jq .

Ce qui donnera :

[
  {
    "DEVNAME": "/dev/mmcblk0p1",
    "LABEL_FATBOOT": "boot",
    "LABEL": "boot",
    "UUID": "5DE4-665C",
    "TYPE": "vfat",
    "PARTUUID": "eac47f08-01"
  },
  {
    "DEVNAME": "/dev/mmcblk0p2",
    "LABEL": "rootfs",
    "UUID": "729c5bb3-bcb2-4267-9ca0-09ef59e10bf0",
    "TYPE": "ext4",
    "PARTUUID": "eac47f08-02"
  }
]

Ou encore, en enlevant un peu de bruit (dépend de votre installation), et en mettant les clés en minuscules :

( echo '[{' ; blkid -o export ; echo '}]' ) |
  sed -E -e 's|^([A-Z_]+)=(.*)$|"\1": "\2",|g' -e 's|^$|},{|g' |
  tr -d '\n' |
  sed -e 's|,}|}|g' -e 's,\\ , ,g' |
  jq 'map( with_entries( .key |= ascii_downcase ) | select( .type != "squashfs" ) )'

On formate un peu et on met dans une fonction :

function blkid_json {
  ( echo '[{' ; blkid -o export ; echo '}]' ) |
  sed -E -e 's|^([A-Z_]+)=(.*)$|"\1": "\2",|g' -e 's|^$|},{|g' |
  tr -d '\n' |
  sed -e 's|,}|}|g' -e 's,\\ , ,g' |
  jq 'map(
        with_entries( .key |= ascii_downcase ) |
        select( .type != "squashfs" )
      )' || return $?
}

Cela donnera :

[
  {
    "devname": "/dev/mmcblk0p1",
    "label_fatboot": "boot",
    "label": "boot",
    "uuid": "5DE4-665C",
    "type": "vfat",
    "partuuid": "eac47f08-01"
  },
  {
    "devname": "/dev/mmcblk0p2",
    "label": "rootfs",
    "uuid": "729c5bb3-bcb2-4267-9ca0-09ef59e10bf0",
    "type": "ext4",
    "partuuid": "eac47f08-02"
  }
]

ඏ

Utilisation de « jc »

En s’appuyant sur le billet 🐚 jc : « JSONifier » les commandes Linux., on peut obtenir la commande Ă©quivalente Ă  l’aide de jc :

Simplement :

jc --pretty blkid | jq 'map( select( .type != "squashfs" ) )'

Ou en cas de conflit avec une autre commande :

/bin/jc --pretty blkid | jq 'map( select( .type != "squashfs" ) )'

On retrouve alors le code produit avec notre « bricolage » Ă  l’aide de sed, tr et de jq. Petit bĂ©mol qui est facile Ă  corriger :

diff --side-by-side <( blkid_json ) <( /bin/jc --pretty blkid | jq 'map( select( .type != "squashfs" ) )' )
  • la fonction blkid_json dĂ©crite plus haut produit un champ devname alors que
  • la commande jc produit un champ device

mais nous n'avons pas besoin de ce champ dans la suite de ce billet.

Attention les anciennes versions de jc ne reconnaissent pas --pretty, utiliser alors -p Ă  la place.


ඏ

Conversion de la sortie de « blkid » en JSON sans « jc », comme « jc »

Si pour la suite, vous ne souhaitez ou vous ne pouvez pas utiliser jc, voici comment obtenir le mĂȘme rĂ©sultat:

  • Annexe

    En partant de la fonction blkid_json, il suffit de renommer le champ devname :

    blkid_json |
      jq '
    map(
      to_entries |
      map(
        if .key == "devname" then . + { key: "device" } else . end
      ) |
      from_entries
    )'
    

    Mais on peut injecter cela directement dans le code initial, comme suit :

    function blkid_jc_json {
      ( echo '[{' ; blkid -o export ; echo '}]' ) |
      sed -E -e 's|^([A-Z_]+)=(.*)$|"\1": "\2",|g' -e 's|^$|},{|g' |
      tr -d '\n' |
      sed -e 's|,}|}|g' -e 's,\\ , ,g' |
      jq 'map(
            with_entries( .key |= ascii_downcase ) |
            select( .type != "squashfs" ) |
            to_entries | map( if .key == "devname" then . + { key: "device" } else . end ) | from_entries
          )' || return $?
    }
    

    Vérifions :

    diff --side-by-side <( blkid_jc_json ) <( /bin/jc --pretty blkid | jq 'map( select( .type != "squashfs" ) )' )
    

ඏ

 Convertir le résultat de « blkid » pour « /etc/fstab »

Pour simplifier le code, on partira de la commande jc, mais l’adaptation à l’aide de la solution à base de sed, tr et jq est triviale.

Ici, on va monter la partition en se basant sur le champ UUID :

function create_fstab_entry_with_uuid {
  local -r key="$1"
  local -r value="$2"
  local -r mount_point="$3"

  /bin/jc -p blkid |
    jq -r --arg K "${key}" --arg V "${value}" --arg M "${mount_point}" '
    .[] |
    select( .[$K] == $V ) |
    "UUID=\"" + .uuid +"\"\t" + $M + "\t" + .type + "\terrors=remount-ro\t0\t2"
' || return $?
}

Exemple d’utilisation :

create_fstab_entry_with_uuid 'label' 'Samsung_2To' '/mnt/data'

Le code recherche la partition ayant pour libellĂ© (« label ») : «  Samsung_2To » et va crĂ©er une entrĂ©e pour le fichier /etc/fstab pour monter la partition dans le dossier /mnt/data (qui doit exister et ĂȘtre vide).

Cela donnera quelque chose comme ça :

UUID="5c39570d-fd27-8646-a746-0b87eef25fb4" /mnt/data   ext4    errors=remount-ro   0   2

Si vous préférer utiliser le champ PARTUUID :

function create_fstab_entry {
  local -r fs_spec_type="$1"
  local -r key="$2"
  local -r value="$3"
  local -r mount_point="$4"

  /bin/jc -p blkid |
    jq -r \
      --arg K "${key}" --arg V "${value}" --arg M "${mount_point}" \
      --arg T "${fs_spec_type}" '
.[] |
select( .[$K] == $V ) |
if $T == "device" then
  .device +"\t" + $M + "\t" + .type + "\terrors=remount-ro\t0\t2"
elif $T == "LABEL" then
  "LABEL=\"" + .label + "\"\t" + $M + "\t" + .type + "\terrors=remount-ro\t0\t2"
elif $T == "PARTLABEL" then
  "PARTLABEL=\"" + .partlabel + "\"\t" + $M + "\t" + .type + "\terrors=remount-ro\t0\t2"
elif $T == "PARTUUID" then
  "PARTUUID=" + .partuuid + "\t" + $M + "\t" + .type + "\terrors=remount-ro\t0\t2"
elif $T == "UUID" then
  "UUID=" + .uuid + "\t" + $M + "\t" + .type + "\terrors=remount-ro\t0\t2"
else
  error( "Unkown: " + $T )
end
' || return $?
}

Exemples d'usage :

create_fstab_entry device    label data /mnt/data
create_fstab_entry LABEL     label data /mnt/data
create_fstab_entry PARTLABEL label data /mnt/data
create_fstab_entry PARTUUID  label data /mnt/data
create_fstab_entry UUID      label data /mnt/data

ඏ

Liens

኿


â„č 2006 - 2024 | 🏠 Accueil du domaine | 🏡 Accueil du blog