Lorsque j'essaie d'imprimer le fichier de périphérique, la sortie affiche des données binaires au format hexadécimal. Mais en faisant un ls -l /dev/sda
je reçois:
brw-rw---- 1 root disk 8, 0 Jan 29 12:29 /dev/sda
Je ne comprends pas quelle est la taille réelle du fichier? Que signifient ces chiffres?
TL; DR : c'est ainsi que les développeurs ont implémenté le ls.c
. En fonction du type de fichier, la chaîne de sortie pour l'option longue -l
sera construite différemment. La documentation de GNU ne mentionne pas la différence de format (voir la note sur la page de manuel d'OpenBSD).
Fichiers de périphérique et code source ls
/dev/sda
est un périphérique en mode bloc (expliqué plus loin dans cette section). C'est différent du fichier normal. ls.c
construit la longue chaîne de sortie en fonction du type de fichier sur lequel elle travaille. Comme indiqué ci-dessous, pour les périphériques en mode bloc, rien sur la taille n'est ajouté à la chaîne de sortie!
ls.c
a les lignes de code suivantes:
3757 static void
3758 print_long_format (const struct fileinfo *f)
3759 {
( partially omited )
3868 if (f->stat_ok
3869 && (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode)))
3870 {
3871 char majorbuf[INT_BUFSIZE_BOUND (uintmax_t)];
3872 char minorbuf[INT_BUFSIZE_BOUND (uintmax_t)];
3873 int blanks_width = (file_size_width
3874 - (major_device_number_width + 2
3875 + minor_device_number_width));
3876 sprintf (p, "%*s, %*s ",
3877 major_device_number_width + MAX (0, blanks_width),
3878 umaxtostr (major (f->stat.st_rdev), majorbuf),
3879 minor_device_number_width,
3880 umaxtostr (minor (f->stat.st_rdev), minorbuf));
3881 p += file_size_width + 1;
3882 }
3883 else
3884 {
3885 char hbuf[LONGEST_HUMAN_READABLE + 1];
3886 char const *size =
3887 (! f->stat_ok
3888 ? "?"
3889 : human_readable (unsigned_file_size (f->stat.st_size),
3890 hbuf, file_human_output_opts, 1,
3891 file_output_block_size));
3892 int pad;
3893 for (pad = file_size_width - mbswidth (size, 0); 0 < pad; pad--)
3894 *p++ = ' ';
3895 while ((*p++ = *size++))
3896 continue;
3897 p[-1] = ' ';
3898 }
Notez que si le type de fichier est S_ISCHR
(périphérique de caractères, flux continu de données) ou S_ISBLK
(périphérique de bloc, accès aléatoire), les numéros de périphérique majeur et mineur sont imprimés dans le tableau de caractères p
(qui est essentiellement une chaîne). C'est la seule donnée ajoutée à la chaîne de sortie p
. Cependant, lorsque nous arrivons à else
part, ls
comprend que nous travaillons avec des fichiers autres que des périphériques block ou character . Pour ces fichiers, il affecte les données stockées dans un tableau de taille aux segments suivants de ce tableau p
size (c'est la partie while ((*p++ = *size++))
.).
L'idée principale est que ls sait quel type de fichier il recherche et crée la sortie en conséquence
Qu'est-ce qu'un fichier de périphérique?
Ce sont essentiellement des références. Ils permettent aux applications de gérer des périphériques physiques réels et leurs pilotes. Par exemple, /dev/sda
et /dev/sr0
(qui est un lecteur de CD/DVD). Certains des appareils ne sont que de l'abstraction. Par exemple, /dev/zero
, /dev/null
et /dev/random
ne sont pas des périphériques physiques. Ce sont des moyens d'interfaçage avec les processus du noyau.
Puisqu'ils sont des références, il est logique qu'ils n'aient pas la taille du fichier . Il est possible de connaître la taille des fichiers qu’ils prennent dans le répertoire /dev
, mais ils ne correspondent pas aux périphériques qu’ils représentent!
Il est donc compréhensible que les développeurs de ls.c
implémentent le code de cette façon. La taille du fichier des références est 99,99% des fois inutile pour une raison quelconque.
Mais les périphériques de bloc, par lesquels on entend généralement les disques durs et les lecteurs USB, sont des périphériques physiques, avec une taille physique réelle, alors comment pouvons-nous savoir cela?
Recherche de la taille des périphériques en mode bloc
Les méthodes ci-dessous montrent comment déterminer la taille d’un disque dur/ssd/USB référencé par un périphérique bloc dans `/ dev /
lsblk
ou lsblk /dev/sda
Sudo blockdev --getsize64 /dev/sda
Sudo fdisk -l /dev/sda
ou Sudo fdisk -l
pour tous les développeursSudo parted /dev/sda print
ou Sudo parted -l
pour tous les développeursawk '{print $1*512}' /sys/class/block/sda/size
awk '{$3=$3*1024;print}' /proc/partitions
ou awk '$4 == "sda1" {$3=$3*1024;print}' /proc/partitions
pour des partitions spécifiques.Notes annexes
/proc/devices
contient la liste de tous les numéros principaux correspondant aux périphériques en mode blocdu
, stat
et find
peuvent vous indiquer la taille de ces références, mais ne sont pas nécessaires dans la vie quotidienne (le cas échéant).512
(comme sous le système de fichiers /sys
), tandis que d'autres - 1024 . C'est une convention dans le monde Unix/Linux, car c'est ainsi que sont alloués les blocs physiques réels sur les disques durs.ls
, page de manuel OpenBSD indique explicitement: "Si le fichier est un caractère spécial ou un fichier spécial bloqué, les numéros de périphérique majeur et mineur du fichier sont affichés dans le champ de taille . " (italique ajouté par moi)Références
Je ne trouve aucune documentation expliquant pourquoi ls
les affiche à la place d'un simple 0
comme du
ou stat
, mais comme le dit Byte Commander, ils sont les numéros de périphérique majeur et mineur de ce fichier spécial. à partir de la source :
if (f->stat_ok
&& (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode)))
{
char majorbuf[INT_BUFSIZE_BOUND (uintmax_t)];
char minorbuf[INT_BUFSIZE_BOUND (uintmax_t)];
int blanks_width = (file_size_width
- (major_device_number_width + 2
+ minor_device_number_width));
sprintf (p, "%*s, %*s ",
major_device_number_width + MAX (0, blanks_width),
umaxtostr (major (f->stat.st_rdev), majorbuf),
minor_device_number_width,
umaxtostr (minor (f->stat.st_rdev), minorbuf));
p += file_size_width + 1;
}
Ce code, qui fait partie de la fonction print_long_format()
, utilisé lorsque le format de sortie est long (qu’il soit avec -l
), utilise les numéros de périphérique à la place de la taille pour caractère et dispositif de bloc.
Pour obtenir la taille réelle du périphérique, plusieurs méthodes sont répertoriées dans cet article Unix & Linux .
Il semble que vous ayez raté le concept de "tout-est-un-fichier".
Dans le monde UNIX, tout (données, périphériques, sockets, ..) est mappé sur un fichier. Ces fichiers ont des types - dans le cas de votre répertoire personnel, vous trouverez (principalement) des fichiers dits classiques (texte, programmes, ...).
Contrairement à ces fichiers normaux, le répertoire/dev contient - ce qui est supposé par son nom - des fichiers de périphérique. Par conséquent, vous trouverez des fichiers de type c haracter, b verrouiller et p ipe représentant des périphériques, par exemple./dev/mem est un fichier qui représente la mémoire de votre système,/dev/ttyACM0 peut être un modem série. Le lien entre ces fichiers (périphérique) et les pilotes responsables est créé à l'aide des nombres majeur et mineur, comme indiqué par ls (et comme expliqué ci-dessus).
La taille d’un périphérique est un attribut spécifique et doit être interrogée à l’aide d’outils spécifiques (comme indiqué dans l’article ci-dessus), car il n’existe pas de moyen unique de traiter cet attribut (un disque SSD peut avoir une taille fixe, mais un port série). peut fournir un flux de données sans fin, il n’ya donc pas de taille fixe,/dev/null a un stockage infini :)).
Vous pouvez lire sur ici: https://en.wikipedia.org/wiki/Everything_is_a_file