Что такое /dev/null в Linux и для чего он используется
Что проверяют
Насколько уверенно вы держитесь в Unix, когда пишете сервис, который кто-то будет запускать под системным менеджером процессов или в контейнере. Для разработчика на Go это ещё проверка, отличаете ли вы отбрасывание данных на уровне ядра от отбрасывания внутри процесса.
Как отвечать
Это символьное устройство, а не обычный файл. Запись в него всегда успешна, данные никуда не сохраняются, а чтение сразу возвращает конец файла. Отсюда два применения: погасить ненужный вывод и получить гарантированно пустой источник данных.
В шелле это перенаправления:
cmd > /dev/null 2>&1 # погасить и вывод, и ошибки
cmd 2> /dev/null # погасить только ошибкиВ Go ту же роль играют два разных инструмента. Константа os.DevNull хранит имя устройства и на Windows раскрывается в NUL, поэтому файл открывают через неё, а не по жёстко прописанному пути. А io.Discard это writer, который выбрасывает байты внутри процесса, без системных вызовов: он для бенчмарков и для отключения логов, но не для потоков дочернего процесса.
Полезная деталь под запуск подпроцессов: у структуры exec.Cmd поля Stdout и Stderr, оставленные пустыми, уже подключаются к нулевому устройству, отдельно открывать файл не нужно.
Где спотыкаются
Пишут 2>&1 > /dev/null и удивляются, что ошибки всё равно в терминале. Порядок важен: сначала stderr дублирует текущий stdout, то есть терминал, и только потом stdout уезжает в устройство.
Глушат stderr у сервиса целиком, чтобы не мусорил. Вместе с мусором исчезают паники и ошибки запуска, и следующий разбор инцидента начинается с пустого журнала.
Путают io.Discard и нулевое устройство. Первый гасит запись внутри своего процесса, а дочерний процесс пишет в собственный дескриптор: если его никто не читает, буфер однажды заполнится и подпроцесс встанет.