$ ls -l /dev/stdin /dev/fd/0 lrwx------ 1 tim tim 64 2011-08-07 09:53 /dev/fd/0 -> /dev/pts/2 lrwxrwxrwx 1 root root 15 2011-08-06 08:14 /dev/stdin -> /proc/self/fd/0 $ ls -l /dev/pts/2 /proc/self/fd/0 crw--w---- 1 tim tty 136, 2 2011-08-07 09:54 /dev/pts/2 lrwx------ 1 tim tim 64 2011-08-07 09:54 /proc/self/fd/0 -> /dev/pts/2
/dev
и его подкаталоги являются файловыми дескрипторами устройств? /dev/fd/0
, /dev/stdin
, /proc/self/fd/0
– все ссылки на /dev/pts/2
. l
в lrwx------
средняя ссылка, что означает c
в crw--w----
означает? Почти все файлы под /dev
являются файлами устройств . В то время как чтение и запись в обычный файл хранит данные на диске или другой файловой системе, доступ к файлу устройства общается с драйвером в ядре, который, как правило, общается с частью аппаратного обеспечения (аппаратное устройство, отсюда и название).
Существует два типа файлов устройств: блочные устройства (обозначенные буквой b
как первый символ на выходе ls -l
) и символьные устройства (обозначенные c
). Различие между блочными и символьными устройствами не является полностью универсальным. Блочные устройства – это такие вещи, как диски, которые ведут себя как большие файлы фиксированного размера: если вы пишете байт с определенным смещением, а затем читаете с устройства с этим смещением, вы получаете этот байт обратно. Символьные устройства – это что-то еще, где запись байта имеет немедленный эффект (например, он испускается на последовательной линии), и чтение байта также имеет немедленный эффект (например, он считывается из последовательного порта).
Значение файла устройства определяется его числом, а не его именем (имя относится к приложениям, но не к ядру). Число фактически представляет собой два числа: основное число указывает, какой драйвер отвечает за это устройство, а младший номер позволяет водителю управлять несколькими устройствами¹. Эти числа отображаются в списке ls -l
, где обычно вы найдете размер файла. Например, brw-rw---- 1 root disk 8, 0 Jul 12 15:54 /dev/sda
→ это устройство является основным 8, второстепенным 0.
Некоторые файлы устройств под /dev
не соответствуют аппаратным устройствам. Тот, который существует в каждой системе unix, равен /dev/null
; запись на него не имеет никакого эффекта, и чтение из него никогда не возвращает никаких данных. Это часто удобно в сценариях оболочки, когда вы хотите игнорировать вывод из команды ( >/dev/null
) или запускать команду без ввода ( </dev/null
). Другими распространенными примерами являются /dev/zero
(который возвращает null bytes ad infinitum ) /dev/urandom
(который возвращает случайные байты до бесконечности ).
Несколько файлов устройств имеют значение, зависящее от процесса, который обращается к нему. Например, /dev/stdin
обозначает стандартный ввод текущего процесса; открытие с того же эффекта, что и дублирование стандартного ввода². Аналогично, /dev/tty
обозначает терминал, к которому подключен процесс. В Linux в настоящее время /dev/stdin
и друзья не реализованы как символьные устройства, а вместо этого являются символическими ссылками на более общий механизм, который позволяет ссылаться на каждый дескриптор файла (в отличие от только 0, 1 и 2 по традиционному методу ); например, /dev/stdin
является символической ссылкой на /proc/self/fd/0
. См. Раздел Как относится / dev / fd к / proc / self / fd /? ,
Вы найдете ряд символических ссылок в /dev
. Это может произойти по историческим причинам: файл устройства был перемещен из одного имени в другое, но некоторые приложения все еще используют старое имя. Например, /dev/scd0
является символической ссылкой на /dev/sr0
под Linux; оба обозначают первое устройство CD. Еще одна причина для символических ссылок – организация: под Linux вы найдете свои жесткие диски и разделы в нескольких местах: /dev/sda
и /dev/sda1
и друзья (каждый диск, обозначенный произвольной буквой, и разделы в соответствии с разделом макет), /dev/disk/by-id/*
(диски, обозначенные уникальным серийным номером), /dev/disk/by-label/*
(разделы с файловой системой, обозначенные меткой, выбранной человеком); и более. Символические ссылки также используются, когда общее имя устройства может быть одним из нескольких; например, /dev/dvd
может быть символической ссылкой на /dev/sr0
, или это может быть ссылка на /dev/sr1
если у вас есть два CD- /dev/sr1
а второй – DVD-ридер по умолчанию.
Наконец, есть несколько других файлов, которые вы можете найти в /dev
по традиционным причинам. Вы не найдете то же самое в каждой системе. В большинстве случаев /dev/log
– это сокет , используемый программами для извлечения сообщений журнала. /dev/MAKEDEV
– это скрипт, который создает записи в /dev
. В современных Linux-системах записи в /dev/
создаются автоматически с помощью udev , obsoleting MAKEDEV
.
¹ В Linux это уже не так, но эта деталь важна только для авторов драйверов устройств.
² Дублирование файлового дескриптора означает создание нового файлового дескриптора, который обращается к тому же файлу, что и первый. Соответствующий системный вызов dup
: open("/dev/stdin", flags)
совпадает с dup(0)
, за исключением того, что новый дескриптор может быть создан с различными режимами доступа.
/dev/
для. /dev/stdin
. Это не указывает статически на /dev/pts/2
или любой другой – просто переключитесь на другой терминал, и вы увидите. /dev/stdin
– стандартный ввод текущего сеанса терминала. Это также пример того, почему это должна быть символическая ссылка. man mknod
и info coreutils 'mknod invocation'
. В общем случае c
обозначает тип устройства chararacter. Для вашего первого вопроса они не являются файловыми дескрипторами, это файлы устройств. (так называемые «узлы dev»)
Эти файлы связаны с драйвером, который обрабатывает устройство с использованием основных и младших номеров. (Например, «136, 2» в вашем выводе ls
относится к драйверу устройства, связанному с основным номером 136, и указывает устройство №2, обрабатываемое этим драйвером.)
Первая буква вывода ls -l
– тип устройства в случае файлов устройства. Если это «c», это символьное устройство, или если оно «b», это блок-устройство.
Для вашего второго вопроса, обратитесь к приведенному выше ответу rozcietrzewiacz.