
Файл /dev/null есть в каждой Linux-системе. Он весит ноль байт, но именно туда ежедневно сливаются терабайты ненужного вывода, а если его удалить, то вовсе падут cron, ssh и половина ваших bash-скриптов. Под катом расскажу, откуда взялась эта «чёрная дыра», почему это не обычный файл, а псевдоустройство, и что на нём завязано.
Битовая корзина и память для записи
Начну издалека — у /dev/null была физическая предшественница, битовая корзина. На телетайпах IBM выбитые из перфоленты и перфокарт кусочки бумаги падали в специальный контейнер, который причастные шуточно звали «bit bucket». Туда отправлялось то, что больше никому не нужно, и обратно оттуда ничего не возвращалось… Очень символично, а айтишники любят символизм, поэтому термин прижился и перекочевал в программирование.
Например, в 1972 году инженеры Signetics выпустили шуточный даташит на микросхему 25120 — по нему это была память только для записи, из которой невозможно ничего прочитать.
Цит.: «Память только для записи Signetics — это полностью интегрированное твердотельное устройство, в котором используются режимы усиления и истощения. Она предназначена для хранения N слов, каждое из которых состоит из 9046 бит (термин N может означать любое число вплоть до бесконечности). Микросхема Signetics WOM, изготовленная по некомплементарной МОП-технологии, содержит устройства с каналами P («P» = пифагорейский), N («N» = наполеоновский) и neu (устройства с каналами neu усиливают или ослабляют сигнал одновременно или хаотично, независимо от полярности затвора, но бывают случаи, когда они вообще ничего не делают)».

Эту небольшую историческую отсылку я сделал, чтобы донести, что история нулевого устройства уже существовала до того, как она появилась в Unix-подобных ОС. Похожие способы отбрасывать ненужный вывод были и в других операционках — в DOS устройство называлось NUL, в OpenVMS использовалось обозначение NL:, в AmigaOS применялся обработчик NIL:, а в JCL на мейнфреймах IBM аналогичную роль выполнял параметр DD DUMMY.
Появление в Unix
Летом 1969 года Кен Томпсон, оставшись в одиночестве почти на месяц (пишут, что жена с новорождённым сыном уехала к родственникам) написал первую версию операционки Unix на языке ассемблера PDP-7. В ноябре 1973 года, когда вышло четвёртое издание руководства программиста, в директории /dev красовалась научная запись о том, что /dev/null — пустой обычный файл. Запись в него работала, но файл при этом рос на диске, и его приходилось время от времени чистить руками.
Год спустя, в пятом издании, /dev/null уже позиционировался как специальный символьный девайс с семантикой «запись всегда успешна, ничего нигде не сохраняется, а чтение сразу возвращает конец файла».

После у этой битовой корзины начала разрастаться семья. Позднее рядом с /dev/null появился /dev/zero, который при чтении возвращает поток нулевых байтов. Интересно, что изначально он был нужен для анонимной памяти под разделяемые библиотеки, а не для затирания дисков. Позже появился /dev/full — устройство, которое всегда отвечает «нет места». В Linux за эти устройства отвечает файл drivers/char/mem.c.
Как устроен /dev/null
Разберу его через ls -l /dev/null:
ls -l /dev/null crw-rw-rw- 1 root root 1, 3 ... /dev/null
Буква c в начале означает character device — символьное устройство. Это точка входа в драйвер, а числа 1 и 3 говорят ядру, какой именно драйвер и какой обработчик вызвать при обращении.
Самое важное — при записи в /dev/null данные никуда не попадают (буквально). Функция write_null в drivers/char/mem.c просто возвращает count, сообщая программе, что указанное количество байтов успешно записано, хотя никаких действий с ними не выполняет. Функция read_null же возвращает ноль, который программа воспринимает как конец файла или EOF.
У файла права 666 — читать и писать может вообще любой пользователь. Это осознанное решение разработчиков, поскольку null должен оставаться доступным всем процессам.
При записи /dev/null не приходится обращаться к диску, поэтому результат зависит от системных вызовов и подготовки данных.
Также /dev/null не каталог, поэтому mv file /dev/null не переместит файл в никуда, а просто заменит собой файл устройства. Если после такой команды у вас внезапно (сам по себе, ага) пропал нормальный null — пора учить mknod.
Что происходит, когда /dev/null исчезает
Немного отвлекусь, в сборнике Unix Administration Horror Stories из девяностых есть история о том, как админ удалил /dev/null, и вскоре он был воссоздан как обычный файл. После этого в системе начались СТРАШНЫЕ-ПРЕСТРАШНЫЕ проблемы с правами, а понять причину он не мог (новичок же ж).
Там же есть перл об очистке битовой корзины — сообщение об ошибке, которое просит почистить мусорку, в которую ничего нельзя выбросить (это мой любимый экспонат юниксового юмора, а другие истории можно почитать тут).

Возвращаюсь к теме, весь шелл-мир /dev/null построен на идиоме «отправь вывод в никуда»:
command > /dev/null 2>&1
Сначала stdout уходит в /dev/null, потом stderr перенаправляется туда же. Если перевернуть конструкцию (2>&1 > /dev/null), то ошибки продолжат сыпаться.
Так вот, если /dev/null удалён, непривилегированные процессы начнут получать ошибки, а какой-нибудь привилегированный может создать вместо него обычный файл null. После появятся другие проблемы:
данные перестанут исчезать,
права доступа станут неподходящими для остальных пользователей,
чтение больше не будет возвращать конец файла.
На современных ОС, где /dev размещён на devtmpfs или tmpfs, такой файл будет есть оперативную память. Если же /dev находится на обычной файловой системе, то под угрозой окажется свободное место на соответствующем разделе. Страшно? Будет ещё страшнее.
Будут проблемы и с cron. Любая задача, вывод которой не отправлен в /dev/null, приводит к письму для владельца задачи, а на сервере без почты эти письма копятся в /var/mail или падают с ошибками в логах. Отключить отправку можно через MAILTO="", а подавить вывод конкретной команды позволяет именно перенаправление в /dev/null.
С ним же связаны и демоны. Процессы, отрывающиеся от терминала, традиционно перенаправляют stdin, stdout и stderr в /dev/null. Если устройства нет, то демон не сможет корректно отцепиться. В systemd та же логика спрятана в директивах StandardOutput=null и StandardError=null, и это тот самый /dev/null.
Также куча утилит при запуске открывает /dev/null как замену пустого входа. В скриптах приёмом «</dev/null» глушат интерактивные программы, которые виснут в ожидании ввода — fsck, некоторые инсталляторы, apt с его вопросами. Без работающего /dev/null такие конструкции будут непредсказуемы, и дебажить это удовольствие сомнительное.
И наконец, /dev/null связан с ssh в цикле:
while read host; do ssh $host uptime done < hosts.txt
Он (такой цикл) может пропустить часть хостов, поскольку SSH читает стандартный ввод и забирает данные из того же файла, который обрабатывает read. Обычно проблему решают параметром -n или перенаправлением ввода из /dev/null, но оба варианта зависят от работоспособности файла.
Проверить, что ваш /dev/null настоящий и живой, можно через:
stat -c 'type=%F mode=%a major=%t minor=%T' /dev/null
В выводе должно быть «type=character special file mode=666 major=1 minor=3». Если там «regular file», у меня для вас плохие новости, и этот раздел вы только что читали не зря.
Восстановить удалённый /dev/null, если что, можно командой:
sudo mknod -m 666 /dev/null c 1 3
mknod создаёт файл устройства, c говорит, что устройство символьное, 1 и 3 — это major и minor. Но, к слову, на живых системах /dev обычно на tmpfs и управляется udev, так что после перезагрузки устройство вернётся и само.
Важно, если на месте /dev/null уже появился обычный файл, то mknod завершится ошибкой File exists. В этом случае сначала удалите неправильный файл:
sudo rm -f -- /dev/null sudo mknod -m 666 /dev/null c 1 3
После этого ещё раз запустите mknod и проверьте результат.
Чем же полезен /dev/null
Самое частое применение, кроме глушения вывода, это очистка файла без его удаления. Если лог держит открытый дескриптор, удалять его нельзя, а вот обнулить можно:
: > /var/log/myapp.log # или дедовским способом cat /dev/null > /var/log/myapp.log
Приложение продолжит писать в тот же файл, место освободится. Однако приём подходит в основном для программ, которые открывают лог в режиме добавления.
Ещё /dev/null удобен как «источник пустоты» на входе. Например, GNU tar умеет распознавать вывод архива в /dev/null и ради оптимизации может пропустить чтение содержимого файлов. Если нужно прочитать файлы, архив следует пропустить через конвейер:
tar -cf - /etc | cat > /dev/null
Если нужен код завершения всего конвейера, вводите:
set -o pipefail tar -cf - /etc | cat > /dev/null
Заодно расскажу про его младшего брата — /dev/full ведёт себя как переполненный диск (любая запись возвращает ENOSPC):
echo test > /dev/full echo: write error: No space left on device
А /dev/zero пригодится, когда нужен файл заданного размера или чистое затирание:
# Файл размером 1 ГиБ, заполненный нулями dd if=/dev/zero of=test.bin bs=1M count=1024 # Записать нули во все доступные логические блоки sudo dd if=/dev/zero of=/dev/sdX bs=1M status=progress
Со второй командой, как вы понимаете, главное не перепутать sdX.
Ну и наконец
/dev/null — редкий случай, когда полезность идеи доказана временем. По мне, это эталон того, как должна выглядеть хорошая абстракция — ноль настроек, ноль документации и ноль сюрпризов.
Делитесь в комментариях, для чего вы используете /dev/null чаще всего.
© 2026 ООО «МТ ФИНАНС»
Комментарии (14)

Granulex
27.08.2026 12:05Возможно, удаление /dev/null – наименее опасный сценарий: оно шумное, ошибки посыпятся сразу, и вы всё почините за минуту. Куда тише проходит его подмена обычным файлом где-нибудь в образе – система работает, скрипты молчат, а корень заполняется незаметно.

UncleAndy
27.08.2026 12:05Как-то по молодости лет перепутал параметры в команде ln и сделал
/dev/nullнекорректным симлинком. Пришлось поразбираться почему это на сервере все рухнуло. :))) Хорошо что сервер был в физическом доступе. :)+

wiki7979
27.08.2026 12:05Как было бы интересно, если бы концепция "все есть файл" была реализована в популярной системе. Сколько бы всего утекло в сеть без каких-либо серьёзных усилий, м-м-м...

randomsimplenumber
27.08.2026 12:05Поясните, что куда и почему утекло, и при чем тут концепция файла.

wiki7979
27.08.2026 12:05Не буду пояснять, ибо минусуютъ.

randomsimplenumber
27.08.2026 12:05За хорошее годное пояснение плюсуют. А за плохое негодное - могут и табуретку выбить.

beswalod
27.08.2026 12:05А кто-нибудь объяснит, зачем какая-то внешняя команда, которая всегда возвращает 0/1/true/false/EOF/etc, если то же самое можно сделать в коде программы, просто написав "return anything;"?

PashaWNN
27.08.2026 12:05Концепция юникса, в которой всё было задумано так, чтобы сложные скрипты строились из максимально простых программ, работающих со стандартным вводом-выводом. Те самые
catи подобные программки. И вот гораздо проще перенаправить ненужный вывод в null, чем городить в программе отдельный флаг, отвечающий за подавление вывода. Т. е. по умолчанию считаем, что пользователь захочет оперировать файлами и даём ему удобный способ, а для ситуаций, когда вывод не нужен/нужны нули вместо файла/что-то ещё такое — даём универсальный способ, который подойдёт для любой программы, которая умеет работать с файлами.
astenix
Где?
Искал-проверял — нет его.
dlinyj
https://github.com/torvalds/linux/blob/73e3f0710014fe6d4ed98cfc02292f6121db7558/drivers/char/mem.c#L415