Размер файла устройств (отсутствующий в ls-l вывод)

То, когда я пытаюсь распечатать вывод файла устройств, показывает двоичные данные в шестнадцатеричном формате. Но после выполнения a ls -l /dev/sda Я добираюсь:

brw-rw----  1 root disk      8,   0 Jan 29 12:29 /dev/sda

Я не понимаю то, что фактический размер файла? Что означают эти числа?

4
задан 31 January 2016 в 09:49

3 ответа

TL; DR: это - то, как разработчики реализовали ls.c. В зависимости от типа файла, выходной строки для долгой опции -l будет наращивание по-другому. Документации GNU не удается упомянуть различие в формате (см. примечание стороны о странице справочника OpenBSD).

Файлы устройств и ls исходный код

/dev/sda блочное устройство (объясненный позже в разделе). Это отличается из регулярного файла. ls.c создает долгую выходную строку согласно тому, какой тип файла она продолжает работать. Как показан ниже, для блочных устройств ничто о размере не добавляется к выходной строке!

ls.c имеет следующие строки кода:

   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     }

Заметьте это, если тип файла S_ISCHR (устройство посимвольного ввода-вывода, непрерывный поток данных) или S_ISBLK (блочное устройство, произвольный доступ), главные и незначительные номера устройств печатаются к символьному массиву p (который является по существу строкой). Это - единственные данные, которые добавляются к выходной строке p . Однако, когда мы добираемся до else часть, ls понимает, что мы работаем с файлами кроме блочных устройств или устройств посимвольного ввода-вывода. Для тех файлов это присваивает данные, хранившие в массиве размера к следующим сегментам этого p массив размера (это while ((*p++ = *size++)) часть).

Центральная идея состоит в том, что ls знает, какой тип файла это смотрит на и создает вывод соответственно

Что такое файлы устройств так или иначе?

По существу они - ссылки. Они - путь к приложениям для контакта с фактическими физическими устройствами и их драйверами. Например, /dev/sda и /dev/sr0 (который является CD/DVD-приводом). Некоторые устройства являются просто абстракцией. Например, /dev/zero, /dev/null, и /dev/random не физические устройства. Они - способы взаимодействовать через интерфейс с процессами ядра.

Так как они - ссылки, это имеет смысл, что у них не было бы размера файла. Возможно знать размер тех файлов, которые они поднимают в /dev каталог, но они не соответствуют существующим устройствам, которые они представляют!

Таким образом это понятно почему ls.c разработчики реализовали код тот путь. Размер файла ссылок составляет 99,99% времен, не нужных по любой причине вообще.

Но блочные устройства, который мы обычно средние жесткие диски и Карты памяти, являются физическими устройствами с реальным физическим размером, поэтому как мы узнаем это?

Обнаружение размера фактических блочных устройств

Методы рева иллюстрируют, как можно было узнать размер диска hard/ssd/USB, на который ссылается блочное устройство в '/dev/

  • lsblk или lsblk /dev/sda
  • sudo blockdev --getsize64 /dev/sda
  • sudo fdisk -l /dev/sda или sudo fdisk -l для всего devs
  • sudo parted /dev/sda print или sudo parted -l для всего devs
  • awk '{print $1*512}' /sys/class/block/sda/size
  • awk '{$3=$3*1024;print}' /proc/partitions или awk '$4 == "sda1" {$3=$3*1024;print}' /proc/partitions для определенных разделов.

Сторона отмечает

  • /proc/devices содержит список всех главных чисел, соответствующих блочным устройствам
  • du, stat и find команды могут показать Вам размер тех ссылок, но не необходимые для повседневной жизни (если вообще)
  • Существует различие между представлением блочных устройств; некоторые файлы реализуют блоки представления 512 (такой как под /sys файловая система), в то время как другие - 1024. Это - конвенция в мире Unix/Linux, так как это - то, как выделяются фактические физические блоки на жестких дисках.
  • В отличие от GNU ls документация, страница справочника OpenBSD явно указывает: "Если файл является символьным специальным предложением или блоком специальный файл, главные и незначительные номера устройств для файла отображены в поле размера". (акцент, добавленный мной)

Ссылки

3
ответ дан 1 December 2019 в 08:59

Кажется пропавшими без вести понятия 'everything-is-a-file'.

В мире UNIX все (данные, устройства, сокеты..) отображается на файле. Те файлы имеют типы - в случае Вашего корневого каталога, который Вы (главным образом) найдете так называемым регулярные файлы (текст, программы...).

В отличие от этих регулярных файлов/dev-directory содержит - подразумеваемый именем - файлы устройств. Поэтому Вы найдете файлы типа c haracter, блокировка b и устройства представления pipe, например,/dev/mem является файлом, который представляет Вашу системную память,/dev/ttyACM0 может быть последовательным модемом. Ссылка между ними (устройство-) файлы и ответственные драйверы создается с помощью главных и незначительных чисел как показано ls (и, как объяснено выше).

размер устройства является устройством определенный атрибут и должен быть запрошен с помощью устройства определенные инструменты (как показано в сообщении выше) причина, там не уникальный способ иметь дело с тем атрибутом (SSD может иметь фиксированный размер - но последовательный порт может поставить бесконечный поток данных, таким образом, нет никакого фиксированного размера,/dev/null имеет бесконечное устройство хранения данных :)).

можно продолжать читать здесь: https://en.wikipedia.org/wiki/Everything_is_a_file

3
ответ дан 1 December 2019 в 08:59

Я не могу найти документацию для почему ls показывает им вместо плоскости 0 как du или stat, но, как Командующий Байта говорит, они - главные и незначительные номера устройств того специального файла. Из источника:

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;
}

Этот код, часть print_long_format() функция, используемая, когда выходной формат долог (с которым это -l), использует номера устройств вместо размера для устройства посимвольного ввода-вывода и блочного устройства.

Для получения фактического размера устройства несколько методов перечислены в этом сообщении Unix & Linux.

4
ответ дан 1 December 2019 в 08:59

Другие вопросы по тегам:

Похожие вопросы: