Что такое /dev/null и как его использовать в Bash
Linux - это интересная операционная система, в которой размещены некоторые виртуальные устройства для различных целей. Для программ, работающих в системе, эти виртуальные устройства действуют так, как будто это реальные файлы. Инструменты могут запрашивать и получать данные из этих источников. Данные генерируются ОС вместо того, чтобы считывать их с диска.
Одним из таких примеров является /dev/null
. Это специальный файл, который присутствует в каждой системе Linux. Однако, в отличие от большинства других виртуальных файлов, вместо чтения он используется для записи. Все, что вы запишете в /dev/null
, будет отброшено, забыто в пустоте. В системе UNIX он известен как нулевое устройство.
Зачем вам выбрасывать что-то в пустоту? Давайте посмотрим, что такое /dev/null
и как он используется.
Предварительно
Прежде чем углубиться в использование /dev/null
, мы должны иметь четкое представление о потоке данных stdout
и stderr
. Ознакомьтесь с этим коротким руководством по stdin, stderr и stdout.
Давайте сделаем небольшое уточнение. При запуске любой утилиты командной строки она генерирует два вывода. Вывод идет на stdout
, а ошибка (если она возникла) - на stderr
. По умолчанию оба этих потока данных связаны с терминалом.
Например, следующая команда выведет строку, заключенную в двойные кавычки. Здесь вывод сохраняется в stdout
.
$ echo "Hello World"

Следующая команда покажет нам статус выхода ранее запущенной команды.
$ echo $?

Поскольку предыдущая команда была выполнена успешно, статус выхода равен 0. В противном случае статус выхода будет другим. Что произойдет, если вы попытаетесь выполнить недопустимую команду?
$ adfadsf $ echo $?

Теперь нам нужно разобраться в файловом дескрипторе. В экосистеме UNIX это целочисленные значения, присвоенные файлу. И stdout
, и stderr
имеют определенный дескриптор файла: stdout = 1
, stderr = 2
. Используя дескриптор файла (1 и 2), мы можем перенаправить stdout
и stderr
в другие файлы.
Cледующий пример перенаправит stdout команды echo в текстовый файл. Здесь мы не указали дескриптор файла. Если он не указан, bash будет использовать stdout по умолчанию.
$ echo "Hello World" > log.txt

Следующая команда перенаправит stderr в текстовый файл.
$ asdfadsa 2> error.txt

Использование /dev/null
Перенаправление вывода в /dev/null
Теперь мы готовы узнать, как использовать /dev/null
. Сначала давайте проверим, как фильтровать обычный вывод и ошибки. В следующей команде grep попытается найти строку (hello, в данном случае) в каталоге "/sys".
$ grep -r hello /sys/

Однако это вызовет множество ошибок, поскольку без привилегий root grep не может получить доступ к ряду файлов. В этом случае он выдаст ошибку "Permission denied". Теперь, используя перенаправление, мы можем получить более четкий результат.
$ grep -r hello /sys/ 2> /dev/null

Вывод выглядит намного лучше, верно? Ничего! В этом случае у grep нет доступа ко многим файлам, а в тех, что есть, нет строки "hello".
В следующем примере мы будем пинговать Google.
$ ping google.com

Однако мы не хотим видеть все эти успешные результаты пинга. Вместо этого мы хотим сосредоточиться только на ошибках, когда ping не смог достичь Google. Как нам это сделать?
$ ping google.com 1> /dev/null

Здесь содержимое stdout
сбрасывается в /dev/null
, оставляя только ошибки.
Перенаправить весь вывод в /dev/null
В некоторых ситуациях вывод может оказаться бесполезным. Используя перенаправление, мы можем сбросить весь вывод в пустоту.
$ grep -r hello /sys/ > /dev/null 2>&1

Давайте немного разобьем эту команду. Сначала мы сбрасываем весь stdout
в /dev/null
. Затем, во второй части, мы говорим bash отправить stderr
в stdout
. В этом примере выводить нечего. Однако, если вы запутались, вы всегда можете проверить, успешно ли выполнилась команда.
$ echo $?

Значение равно 2, потому что команда выдала много ошибок.
Если вы склонны забывать файловый дескриптор stdout и stderr, следующая команда подойдет как нельзя лучше. Это более обобщенный формат предыдущей команды. И stdout, и stderr будут перенаправлены в /dev/null.
$ grep -r hello /sys/ &> /dev/null

Другие примеры
Это интересный пример. Знаете инструмент dd
? Это мощный инструмент для преобразования и копирования файлов. Узнайте больше о dd
. Используя dd
, мы можем проверить скорость последовательного чтения вашего диска. Конечно, это не точное измерение. Однако для быстрого теста это довольно полезно.
$ dd if=<big_file> of=/dev/null status=progress bs=1M iflag=direct

Здесь я использовал Ubuntu 18.04.4 ISO в качестве большого файла.
Аналогичным образом вы также можете проверить скорость загрузки вашего интернет-соединения.
$ wget -O /dev/null <big_file_link>
--
Надеемся, у вас есть четкое понимание того, что такое файл /dev/null. Это специальное устройство, которое при записи в него отбрасывает, а при чтении из него считывает null. Истинный потенциал этой интересной возможности заключается в интересных bash-скриптах.
Вас интересуют сценарии на bash? Ознакомьтесь с руководством для начинающих по написанию сценариев на bash.
--