Aujourd’hui on va s’intéresser à l’arborescence '/dev' de votre Linux. J’ai fait ces recherches pour le projet prepare-raspbian-sd avec l’objectif de détecter la carte SD et de connaître le périphérique rattaché.
Le mot anglais « device » signifiant dispositif, appareil. En informatique il est utilisé pour parler d’un dispositif ajouté à l’ordinateur, un appareil périphérique. En français on simplifie cela par le mot périphérique. En anglais informatique ce mot « device » est souvent abrégé par « dev ».
Le dossier /dev
contient les caractéristiques des périphériques présents sur la machine. Ici, nous nous intéresserons principalement aux périphériques de stockage, mais par exemple votre souris ou votre webcam est également décrite dans cette arborescence.
Quelques astuces simples :
Par labelle
Le dossier /dev/disk/by-label/
contiens, comme il l’indique son nom, la liste des labelles (étiquette, nom du disque) de vos disques. On peut le constater simplement à l’aide de :
ls -l --color /dev/disk/by-label/
Par exemple, sur un Raspberry
standard (le seul disque dur est une carte SD avec deux partitions) :
lrwxrwxrwx 1 root root 15 Aug 5 00:08 boot -> ../../mmcblk0p1
lrwxrwxrwx 1 root root 15 Aug 5 00:08 rootfs -> ../../mmcblk0p2
On retrouve bien les 2 partitions Raspberry Pi OS
nommées boot et ** rootfs**, l’utilisation du paramètre -l permet de voir que ces fichiers sont des liens.
labelle | lien | Chemin réel du fichier cible |
---|---|---|
boot | ./../mmcblk0p1 | /dev/mmcblk0p1 |
rootfs | ./../mmcblk0p2 | /dev/mmcblk0p2 |
Les fichiers se trouvant directement sous /dev
ne sont pas lisibles directement (et ne doivent par être utilisé en dehors de manipulations spécifiques) mais ils correspondent au contenu brut des données de la partition.
Par identificateur
Le dossier /dev/disk/by-id/
contiens, la liste des identificateurs (id) de vos disques. De même :
ls -l --color /dev/disk/by-id/
Par exemple, ici le cas encore le cas de Raspberry Pi OS
de base :
lrwxrwxrwx 1 root root 13 Aug 5 00:08 mmc-ACLCD_0x84153af7 -> ../../mmcblk0
lrwxrwxrwx 1 root root 15 Aug 5 00:08 mmc-ACLCD_0x84153af7-part1 -> ../../mmcblk0p1
lrwxrwxrwx 1 root root 15 Aug 5 00:08 mmc-ACLCD_0x84153af7-part2 -> ../../mmcblk0p2
Ici, vous noterez il semble qu’il y ait 3 partitions :
identificateur | lien | Chemin réel du fichier cible |
---|---|---|
mmc-ACLCD_0x84153af7 | ./../mmcblk0 | /dev/mmcblk0 |
mmc-ACLCD_0x84153af7-part1 | ./../mmcblk0p1 | /dev/mmcblk0p1 |
mmc-ACLCD_0x84153af7-part2 | ./../mmcblk0p2 | /dev/mmcblk0p2 |
En réalité /dev/mmcblk0
est le fichier correspondant à l’ensemble du disque. Les fichiers /dev/mmcblk0p1
et /dev/mmcblk0p2
étant les deux partitions de ce disque.
Sur une autre machine, on a quelque chose comme cela :
lrwxrwxrwx 1 root root 9 Aug 5 00:04 ata-Samsung_Portable_SSD_T5_S4B1NV0M71Y -> ../../sda
lrwxrwxrwx 1 root root 10 Aug 5 00:04 ata-Samsung_Portable_SSD_T5_S4B1NV0M71Y-part1 -> ../../sda1
lrwxrwxrwx 1 root root 13 Aug 5 00:04 mmc-SC128_0x79314ba7 -> ../../mmcblk0
lrwxrwxrwx 1 root root 15 Aug 5 00:04 mmc-SC128_0x79314ba7-part1 -> ../../mmcblk0p1
lrwxrwxrwx 1 root root 15 Aug 5 00:04 mmc-SC128_0x79314ba7-part2 -> ../../mmcblk0p2
lrwxrwxrwx 1 root root 9 Aug 5 00:04 wwn-0x5000002538e00000 -> ../../sda
lrwxrwxrwx 1 root root 10 Aug 5 00:04 wwn-0x5000002538e00000-part1 -> ../../sda1
Ici on comprend qu’il y a deux périphériques de stockage (disque dur, carte SD…). On note que le périphérique /dev/sda
et son unique partition ont deux identificateurs.
Allons un peu plus loin à la recherche de nos cartes SD
On ne peut pas s’appuyer sur le nom (par exemple mmcblk0) pour identifier une carte SD. Cela de comment elle est connectée au système (avec un adaptateur USB externe par exemple). Il va donc falloir aller un peu plus loin pour rechercher nos cartes SD.
Le répertoire /sys/block
contient un lien symbolique pour chaque périphérique de bloc (comme les unités de stockage) qui a été découvert sur le système. Les liens symboliques pointent vers les répertoires correspondants sous /sys/devices
.
Le répertoire /sys/devices
contiens une représentation du système de fichier. Il définit la structure des périphériques connue par le noyau du système. Il s’agit de la hiérarchie des périphériques tel qu’elle a été prise en compte par le système.
L’idée est de parcourir les blocs systèmes liés à un périphérique pour cela on va lister le dossier /sys/block
et pour chacune de ces entrées, on va suivre le lien (donc se retrouver dessus : /sys/devices
) et là on va se limiter aux dossiers contenant un sous-dossier device.
Cette méthode qui peut sembler obscure, permet de filtrer les périphériques supportant la gestion en blocs.
Le code est le suivant :
for DEV in /sys/block/* ; do
if [ -d "${DEV}/device" ] ; then
echo "${DEV} -> $( realpath "${DEV}" ) - ${DEV}/device/ -> $( realpath "${DEV}/device" )"
ls -la --color "${DEV}/device/"
fi
done
Le même code, plus difficile à lire (mais cela fait la même chose promis) et qui affiche ce qu’il se passe avec des codes couleurs.
function show_bloc_with_device {
YELLOW=$'\033[0;33m'
LIGHT_YELLOW=$'\033[1;33m'
CYAN=$'\033[0;36m'
LIGHT_CYAN=$'\033[1;36m'
NOCOLOR=$'\033[0m'
for DEV in /sys/block/* ; do
if [ -d "${DEV}/device" ] ; then
cat <<EOF
${YELLOW}${DEV}${NOCOLOR} -> ${LIGHT_YELLOW}$( realpath "${DEV}" )${NOCOLOR}
${CYAN}${DEV}/device/${NOCOLOR} -> ${LIGHT_CYAN}$( realpath "${DEV}/device" )${NOCOLOR}
-----
${YELLOW}ls -la --color "${DEV}"${NOCOLOR}
$( ls -la --color "${DEV}" )
-----
${LIGHT_YELLOW}ls -la --color "${DEV}/"${NOCOLOR}
$( ls -la --color "${DEV}/" )
-----
${CYAN}ls -la --color "${DEV}/device"${NOCOLOR}
$( ls -la --color "${DEV}/device" )
-----
${LIGHT_CYAN}ls -la --color "${DEV}/device/"${NOCOLOR}
$( ls -la --color "${DEV}/device/" )
EOF
fi
done
}
show_bloc_with_device
On comprend que la zone est remplie de lien symbolique et que c’est en les suivants que l’on va pouvoir filtrer ce qui nous intéresse.
Et en fait, on y est presque puisque le dossier ${DEV}/device/
, s’il existe, contiens un fichier nommé type
qui va nous éclairer sur la nature du support.
function show_type_for_bloc_with_device {
YELLOW=$'\033[0;33m'
LIGHT_YELLOW=$'\033[1;33m'
CYAN=$'\033[0;36m'
LIGHT_CYAN=$'\033[1;36m'
NOCOLOR=$'\033[0m'
for DEV in /sys/block/* ; do
if [ -d "${DEV}/device" ] ; then
cat <<EOF
${YELLOW}${DEV}${NOCOLOR} -> ${LIGHT_YELLOW}$( realpath "${DEV}" )${NOCOLOR}
${CYAN}${DEV}/device/${NOCOLOR} -> ${LIGHT_CYAN}$( realpath "${DEV}/device" )${NOCOLOR}
-----
${LIGHT_CYAN}cat "${DEV}/device/type"${NOCOLOR}
$( cat "${DEV}/device/type" )
EOF
fi
done
}
show_type_for_bloc_with_device
On constate alors que lorsqu’il s’agit d’une carte SD, le contenu du fichier type
contiens la valeur SD
. Et comme le nom de base en partant de /sys/block/
est le nom du périphérique, on peut utiliser ce nom (sans le chemin) et le préfixé par `/dev/’ pour avoir le chemin technique.
Finalement le code donnant la solution est très compact :
function get_SD_device {
local dev_path=
for dev_path in /sys/block/* ; do
if [ -f "${dev_path}/device/type" ] ; then
if [ "$( cat "${dev_path}/device/type" )" = 'SD' ] ; then
basename "${dev_path}"
fi
fi
done
}
SDDEV="$( get_SD_device )" &&
echo "SDDEV='${SDDEV}'" &&
if [ -z "${SDDEV}" ] ; then echo "#NOSD" ; else ls -l --color "/dev/${SDDEV}"* ; fi
Références
- Manuel de sysfs en anglais.
ᦿ