Что такое /dev/null в Linux?

  Дмитрий Бушуев  | 

  Обновл. 14 Окт 2021  | 

 10399

 ǀ   4 

С технической точки зрения /dev/null в Linux — это файл виртуального устройства. Программы и утилиты могут взаимодействовать с ним как с настоящим файлом: запрашивать данные, а также отправлять в него любую информацию. Но всё, что вы пишете в /dev/null, отправляется в пустоту и забывается (другими словами, отправляется в чёрную дыру). Чтобы понять, почему это полезно, вы должны сначала иметь базовое представление о стандартном потоке вывода данных (stdout) и стандартном потоке вывода ошибок (stderr).

stdout и stderr

Всякий раз, когда запускается какая-либо утилита командной строки, она генерирует два типа вывода: стандартный вывод выполнения команды отправляется в stdout, а сообщения об ошибках (если таковые есть) — в stderr.

По умолчанию stdout и stderr связаны с окном терминала (или консолью). Это означает, что всё, что отправляется в stdout и stderr, обычно отображается на нашем экране. Но с помощью перенаправления вывода мы можем изменить это поведение. Например, мы можем перенаправить вывод stdout в файл. Таким образом, вместо отображения информации о выполнении команды на экране терминала, она будет сохранена в файле, который мы позже сможем прочитать. Или же можно перенаправить stdout на физическое устройство, скажем, на цифровой ЖК-дисплей.

В Linux-системах stdout имеет файловый дескриптор 1, а stderr — файловый дескриптор 2. Используя данные дескрипторы, мы можем перенаправлять вывод из stdout и stderr в другие файлы:

   1> используется для перенаправления стандартного вывода данных (stdout);

   2> используется для перенаправления вывода сообщений об ошибках (stderr). Например, 2>/dev/null отправляет сообщения об ошибках в «чёрную дыру», а 2>/home/user/error.log — в файл error.log.

   &> используется для перенаправления как стандартного вывода данных (stdout), так и вывода сообщений об ошибках (stderr).

/dev/null как средство избавления от ненужного вывода


Допустим, нам нужно найти файлы в каталоге /sys, которые относятся к настройкам питания:

grep -r power /sys/

В выводе команды будет много файлов, которые обычный пользователь (не root) не сможет прочитать (мы получим сообщение об ошибке «Отказано в доступе»). Эти сообщения загромождают терминал и затрудняют поиск. Поскольку ошибки «Отказано в доступе» являются частью stderr, то мы можем перенаправить их в «чёрную дыру», используя /dev/null:

grep -r power /sys/ 2>/dev/null

Как вы можете видеть, теперь результат воспринимается гораздо проще.

В других случаях может быть полезно сделать обратное: отфильтровать стандартный вывод, чтобы мы могли видеть только ошибки, например:

ping ravesli.com 1>/dev/null

На вышеприведенном скриншоте показано, что без перенаправления команда ping отображает свой обычный вывод. Во второй команде ничего не отображается, пока сеть подключена, но как только она отключается, выводится (только) сообщение об ошибке.

Мы можем перенаправить как stdout, так и stderr в два разных места:

ping google.com 1>/dev/null 2>error.log

В этом случае стандартный вывод выполнения команды не будет отображаться вовсе, а сообщения об ошибках будут сохранены в файле error.log.

Перенаправление всего вывода в /dev/null

Иногда полезно избавиться от всех выходных данных. Есть два способа сделать это:

grep -r power /sys/ >/dev/null 2>&1

Часть >/dev/null означает «перенаправить данные из stdout в /dev/null», а часть 2>&1 означает «перенаправить данные из stderr в stdout». Таким образом мы перенаправили весь вывод команды в пустоту.

Примечание: В этом случае мы должны ссылаться на стандартный вывод (stdout) при помощи знака амперсанда — &1, а не просто 1. Запись 2>1 перенаправит данные из stdout в файл с именем 1.

Стоит отметить, что здесь очень важен порядок: если вы измените параметры перенаправления следующим образом:

grep -r power /sys/ 2>&1 >/dev/null

…то это сработает не так, как задумывалось. Часть 2>&1 перенаправит stderr в stdout, отобразит вывод на экране, после чего перенаправит stdout в /dev/null. Конечным результатом станет то, что вместо искомой информации вы увидите сообщения об ошибках. Если вы не можете запомнить правильный порядок составляющих, есть более простое перенаправление:

grep -r power /sys/ &>/dev/null

В этом случае &>/dev/null эквивалентно выражению «перенаправить как stdout, так и stderr в /dev/null».

Еще примеры использования /dev/null


Допустим, мы хотим посмотреть, как быстро наш диск может считывать последовательные данные. Тест не очень точный, но его вполне достаточно. Для этого мы можем использовать команду dd. С помощью of=/dev/null мы можем указать команде dd, что данные следует отправлять в /dev/null. Параметр if= указывает местоположение файла-источника, из которого будут считываться данные:

dd if=<файл-источник> of=/dev/null status=progress bs=1M iflag=direct

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

wget -O /dev/null https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-11.1.0-amd64-netinst.iso


Заключение

/dev/null — это файл виртуального устройства, который при записи в него всё отправляет в пустоту, а при чтении из него — считывает ноль. Истинный потенциал /dev/null очень хорошо раскрывается в различных bash-сценариях.


Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (14 оценок, среднее: 4,93 из 5)
Загрузка...

Комментариев: 4

  1. muctex:

    Отличная статья, простым и понятным языком.
    Спасибо!

  2. Евгений:

    На первый взгляд, первый пункт — странный пример применения /dev/null. Напрашивается вопрос: нет возможности попросту НЕ допускать вывод ненужного информационного мусора, чем обязательно сливать его в /dev/null?

  3. Алекс:

    Спасибо вам за интересный и полезный цикл статей.

    1. Фото аватара Дмитрий Бушуев:

      Всегда пожалуйста. 🙂

Добавить комментарий для Евгений Отменить ответ

Ваш E-mail не будет опубликован. Обязательные поля помечены *