# \[info+script\] 📍 Montage partition + image iso/disque + Squashfs pour l'usager lambda

**URL:** <https://www.debian-fr.org/t/info-script-montage-partition-image-iso-disque-squashfs-pour-lusager-lambda/90310>\
**Category:** Trucs et Astuces\
**Created:** [Septembre 10, 2024, 9:38 UTC](https://www.debian-fr.org/t/info-script-montage-partition-image-iso-disque-squashfs-pour-lusager-lambda/90310 "2024-09-10T21:38:46Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Verner](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/v/34f0e0/32.png) [@Verner](https://www.debian-fr.org/u/Verner)\
**Post date:** [Septembre 10, 2024, 9:38 UTC](https://www.debian-fr.org/t/info-script-montage-partition-image-iso-disque-squashfs-pour-lusager-lambda/90310/1 "2024-09-10T21:38:46Z")

</div>

Sujet montage partitions et images disque qui pourrait paraître simple, mais qui ne l’est pas si on ne se pose pas les bonnes questions.  
Quelques recommandations, à toutes fins utiles, chacun ayant sa perception du problème, en considérant qu’il n’existe pas de règles absolues dans un univers à solutions multiples.  
―――  
Dans la suite, on distinguera très explicitement **deux** types de montage:  
**1** - le montage des partitions système impliquant fstab/systemd dont l’accès doit être exclusivement réservé à l’administrateur, et personne d’autre;  
**2** - tout ce qui n’est pas système, c’est-à-dire à un usager lambda, ou une session invité, de pouvoir monter un périphérique externe pour lecture/écriture, ou une image disque, fichier iso hybride (ou non), Squashfs etc etc, pour en lire le contenu.

C’est le cas N°2 qui concerne ce sujet: **l’usager lambda, en environnement bureau**.

🔵 **Les commandes** :  
Beaucoup d’outils dans l’historique des solutions, de la confusion, selon le backend utilisé, en passant par udevil, udev, udisks, udisks2, gvfs, kio, fuse, avec des terminologies telles que polkit, policykit pour gérer les droits. On s’y perd vite pour comprendre le rôle précis de chaque élément impliqué, ou redondant à éviter.

Sauf cas très particulier où l’usager unique est aussi l’administrateur, **mount** est une commande qui ne doit pas être utilisée dans un environnement bureau pour un montage de périphérique externe pour les raisons suivantes:  
 → par défaut, mount est uniquement accessible à l’administrateur pour une opération de montage/démontage.  
 → mount est trop bas niveau pour interagir directement avec l’utilisateur;  
 → on n’imaginerait pas un administrateur mettre chaque utilisateur dans un groupe ‹&nbsp;sudo&nbsp;› pour l’autoriser à écouter sa musique sur son périphérique externe, et accessoirement bricoler un fstab, et casser le système, avec un doigt qui fourche sur le clavier.

**pmount** par exemple, s’appuie sur HAL (Hardware Abstraction Layer), et ne comprend pas D-bus/udev/udisks2; peut donc encore convenir en usage terminal, mais pas nécessaire ( [pmount **2011**](https://alioth-archive.debian.org/releases/pmount/pmount/) ).

S’il est possible de cliquer sur un icône pour monter une clef USB, c’est que la commande existe déjà, sans rien installer de spécifique. Elle s’appelle **udisksctl** , fournie par udisks2 normalement installé.

**udisksctl** crée automatiquement les points de montage sous `/media/<user>/...` (par défaut le **label** si existant, ou **PARTUUID** ):  
 → inutile de bricoler fstab ou des points de montage sous `/media/<user>/`, espace réservé à udisks.  
 → udisksctl ne gère pas des permissions user/group d’écriture sur un disque, ce n’est pas sa fonction.

🔵 Limitation de confusion d’ **identification des partitions** :  
Afin d’éviter toute confusion, on ne désigne pas dans un script une partition par son inode (ex: /dev/sdc3), parce-qu’un script ne peut pas prédire quel inode sera utilisé lorsque plusieurs périphériques externes sont connectés.  
 → définir un **label clair** , explicite, **unique** et sans espaces pour identifier une partition;  
 → le PARTUUID peut aussi être utilisé de manière très fiable, bien que moins expressif, mais indiquant le N° de partition, toujours mieux que l’UUID dont la combinaison de l’ordre de { 36 puissance 32 } caractères est ridiculement élevée pour distinguer 3 malheureux périphériques.

> remarque:  
> L’avantage du PARTUUID n’est valable essentiellement que pour une table de partitions de type **MBR**.  
> Pour le **GPT** , c’est plus aléatoire, selon l’outil utilisé pour le partitionnement.

Exemple d’identification /dev/sdc5

```plaintext
 LABEL : backup
 PARTUUID : 7a092ff8-05
 UUID : 423dg594-9412-4940-a9c8-37f22565498c

```

🔵 Comment mettre un **label** (étiquette) à une partition:  
Avec `e2fsprogs` installé, pour ext2/3/4:  
`# e2label /dev/sdxy monlabel`  
ou :  
`# tune2fs /dev/sdxy -L monlabel`  
ou pour du vfat, avec `dosfstools` installé:  
`# dosfslabel /dev/sdxy monlabel`

🔵 Gestion du «&nbsp; **mot de passe** &nbsp;» nécessaire au **montage**  
 → rien à voir avec des permissions d’écriture.  
La gestion ciblée des droits ‹&nbsp;sudo&nbsp;› par commande et utilisateur est possible, mais un éventuel remplacement de ‹&nbsp;`sudo`&nbsp;› par ‹&nbsp;`doas`&nbsp;› par exemple, obligerait à tout reconsidérer: très vite un casse-tête.  
Pour monter une partition de périphérique type disque externe, par défaut, une fenêtre s’ouvrira pour demander un mot de passe.  
Si considéré superflu par l’administrateur, c’est facilement contournable en autorisant par exemple les utilisateurs du groupe **plugdev** à monter les partitions, en ajoutant une règle policykit dans un fichier ‹&nbsp;`/etc/polkit-1/rules.d/10-udisks2.rules`&nbsp;› qui contient:

```auto
// Allow udisks2 to mount devices without authentication
// for users in the "plugdev" group.

polkit.addRule(function(action, subject) {
    if ((action.id == "org.freedesktop.udisks2.filesystem-mount-system" ||
         action.id == "org.freedesktop.udisks2.filesystem-mount" ||
         action.id == "org.freedesktop.udisks2.loop-delete-others") &&
        subject.isInGroup("plugdev")) {
        return polkit.Result.YES;
    }
});

```

On vérifie que l’utilisateur est bien dans le groupe ‹&nbsp; **plugdev** &nbsp;› avec la commande `groups`, sinon, l’administrateur le rajoute.

🔵 Les **droits d’écriture** sur le disque:  
Si les répertoires du disque appartiennent à l’utilisateur, ou à son groupe, il n’y a aucune raison de ne pas pouvoir y écrire si le disque n’est pas monté en read-only.  
Si des répertoires ont précédemment été créés avec des vilains ‹&nbsp;sudo&nbsp;›, il suffit de redéfinir correctement les droits.  
`# chown -R toto:users <mon rep>`, pouvant être directement le point de montage, à faire au premier montage: le file-system de la partition montée retiendra les droits demandés lors du prochain montage.

Autre possibilité plus générique pour de l’ **ext** 2/3/4: pré-optionner la partition pour en définir l’utilisateur par défaut, option de permission qui sera prise en compte lors de l’opération de montage:  
`# tune2fs -u 1000 -g 1000 /dev/sdxy`

🔵 Un **script** générique de montage: **Mount**  
Passons à la pratique avec un script que j’appelle **Mount** , un couteau suisse pour monter des partitions (cas le plus simple), mais aussi des images isos hybrides à au moins deux partitions (vfat + iso par exemple), ou un fichier Squashfs, qui a évolué selon des cas particuliers que j’ai rencontrés lors de tests de fichiers disques exotiques.  
Il est bien évidemment sur-spécifié pour monter une partition, mais lors du démontage (-u), vérifie que la partition peut être démontée ‹&nbsp;proprement&nbsp;› en signalant les applications en cours d’utilisation.  
 → Monter une partition est une chose, mais la **dé** monter correctement est fondamental pour ne pas risquer de corrompre le file-system, ce qui nécessiterait une opération de vérification avant tout remontage. Ce point est généralement négligé. Forcer un démontage récalcitrant n’est pas une bonne habitude.

Avec une prise en main de quelques essais, et un ‹&nbsp;help&nbsp;› suffisamment explicite, ça ne devrait pas poser de problèmes d’usage.  
――――――――――――――――――――――――――  
**Mount**

```auto
#!/bin/bash
# 20240910
# script de montage/démontage udisks2.
# monte/démonte: partition, iso, image disque, squashfs
#----------------------------------------------
[[$1 = -h]] && { cat <<EOF |sed 's/Mount/\x1b[33m&\x1b[m/g'
 Usage: Mount <option> FICHIER/OBJET

 Description:
  script de montage partitions, fichiers de type
  image disque ou ISO ou Squashfs, avec quelques vérifications d'usage,
  pour usage en environnement bureau, tout utilisateur.
  Utilisation en espace <user>, ne nécessite ni sudo, mount, ou bricolage fstab
  Le montage udisks se fait sous /media/<user>/...
  -> lecture seule pour images/isos/squashfs
  -> mode écriture pour partitions
  Les points de montage sont automatiquement créés.
  Le nom de montage est le Label partition si existant (recommandé).
  Nécessite le paquet util-linux, et lsof pour détection occupation disque.

 * Sans argument, la liste des block-devices disponibles est affichée
 * Partition en argument, identifiée indifféremment par soit:
   /dev/.... ou Label, ou PartUUID, ou UUID.
 * détecte les applications en cours bloquant un démontage 'propre'

 Options:
 -u: (=unmount) démontage
     sans argument, liste les points de montage actifs sous /media/<user>/
 -c: nettoyage des /dev/loops résiduels inutilisés (non essentiel)
 -h: ce message d'aide

 Exemples:
    Mount ; Mount -u ; Mount /dev/sdc9 ; Mount -u 7a970ff8-05
    Mount <label> ; Mount -u <point de montage>
    Mount sparkylinux-lxqt.iso ; Mount linuxfs ; Mount bookworm_dev.img
EOF
exit
}
[[$1 = -?]] && { a=$1; I=$2; } || { I=$1; a=$2; }
#--------------------------
V='PATH,FSTYPE,LABEL,MOUNTPOINTS,PARTUUID'
lsb() { lsblk -lpo $V -x PATH |awk '$3~/./' ; }

if [[-z $I]] ; then
  case $a in
 -c) while read x ; do udisksctl loop-delete -b $x
     done < <(lsblk -no PATH -x PATH |grep -o '/dev/loop[^p]*' |sort -u)
     lsblk -lpo $V -x PATH |awk '/loop/' ; exit 0 ;;
 -u) lsb |sed -n "1p;\%/media/%p" ;;
  *) lsb ; exit ;;
  esac
 else
  case $a in
 -u) #---| Démontage |---
  D=$(lsb |sed -n "\%${I}%{s/ .*//p;q}")
  ["$D"] && echo " -> démontage $D" || exit
  msg() { if [-f /usr/bin/lsof] ; then
          printf "――\n$I est peut-être en cours d'utilisation par une application\n"
          lsof +f -- $(lsblk -no PATH,MOUNTPOINTS |sed -n "\%${D}%s/[^]* //p") | \
          awk 'NR>1{print $1,$9}'
        else echo "lsof est manquant"
          fi ; }
  [$D = ${D/\/loop/}] && { udisksctl unmount -b $D 2>/dev/null || msg ; } || \
  { [$D = ${D/p*p/}] || D="${D%p*}"
    L=$(lsblk -no PATH,MOUNTPOINTS |sed -n '\%/loop%p')
    for x in $(ls -r ${D}*); do udisksctl unmount -b $x 2>/dev/null; done
    udisksctl loop-delete -b $D 2>/dev/null
    lsblk -no $V | grep "$D" && msg ; }
 ;;
 *) #---| Montage |---
  if [-s "$I"] ; then # fichier image|iso|squashfs
    file -b "$I"
    D=$(udisksctl loop-setup --file "$I" --read-only |grep -o '/dev/loop[^.]*')
    echo " -> $D"
    for x in ${D}* ; do udisksctl mount -b $x 2>/dev/null; done
  else V1="${V},UUID" # partition
    A=$(LC_ALL=C lsblk -Po $V1 |sed -n "\%=\"${I}\"%{s/\" /\n/g;s/\"//g;p}")
    [[$A]] && D=$(sed -n '/PATH/s/.*=//p' <<< "$A") || \
    { echo " ‘${I}’ non accessible"; lsb ; exit; }
    grep -q 'FSTYPE=$' <<< "$A" && echo "Partition non formatée" && exit
    grep -q 'MOUNTPOINTS=.' <<< "$A" && \
    { echo "Partition $I déjà montée"; lsb |sed -n "1p;\%${D}%p"; exit; }
    grep -q 'LABEL=$' <<< "$A" && \
    echo "La partition ‘${I}’ n'a pas encore de label; c'est dommage"
    # montage / Point de Montage passé à la variable PM
    PM=$(udisksctl mount -b $D |grep -o '/media/[^.]*$')
    [[$PM]] && lsb |sed -n "1p;\%${PM}%p"
  fi
  ;;
  esac
fi
#--------------------------
exit

```

――――――――――――――――――――――――――  
Exemples:

```plaintext
$ Mount
  PATH FSTYPE LABEL MOUNTPOINTS PARTUUID
  /dev/sda1 ext2 sda1 7a579ff8-01
  /dev/sda2 ext4 devuan 7a579ff8-02
  /dev/sda3 ext4 trixie / 7a579ff8-03
  /dev/sda5 ext4 S5_home /home 7a579ff8-05
  /dev/sda6 ext4 S6_extra /mnt/extra 7a579ff8-06
  /dev/sda7 ext4 backup 7a579ff8-07

$ Mount backup
  PATH FSTYPE LABEL MOUNTPOINTS PARTUUID
  /dev/sda7 ext4 backup /media/user1/backup 7a579ff8-07

$ Mount TinyCore-current.iso
  ISO 9660 CD-ROM filesystem data (DOS/MBR boot sector) 'TinyCore' (bootable)
   -> /dev/loop0
  Mounted /dev/loop0p1 at /media/user1/TinyCore

$ Mount easy.sfs
  Squashfs filesystem, little endian, version 4.0, zstd compressed
   -> /dev/loop1
  Mounted /dev/loop1 at /media/user1/disk

$ Mount sparkylinux-2024.05-x86_64-lxqt.iso
  ISO 9660 CD-ROM filesystem data (DOS/MBR boot sector) 'SPARKY_64bit' (bootable)
  -> /dev/loop2
  Mounted /dev/loop2p1 at /media/user1/SPARKY_64bit
  Mounted /dev/loop2p2 at /media/user1/6484-3985

$ Mount -u
  PATH FSTYPE LABEL MOUNTPOINTS PARTUUID
  /dev/loop0p1 iso9660 TinyCore /media/user1/TinyCore 1a8d81de-01
  /dev/loop1 squashfs /media/user1/disk
  /dev/loop2p1 iso9660 SPARKY_64bit /media/user1/SPARKY_64bit 05aa05a3-01
  /dev/loop2p2 vfat /media/user1/6484-3985 05aa05a3-02
  /dev/sda7 ext4 backup /media/user1/backup 7a579ff8-07

$ Mount -u SPARKY_64bit
  -> démontage /dev/loop2p2
  Unmounted /dev/loop2p2.
  Unmounted /dev/loop2p1.

```
