В вопросе о переполнении стека Проверьте, существует ли программа из сценария bash в принятый ответ отмечает, что закрытие stderr опасно:
(небольшое примечание: некоторые предложат 2> & - то же самое 2> / dev / null, но короче - это неверно. 2> & - закрывает FD 2, что вызывает ошибку в программе при попытке записи в stderr , что сильно отличается от успешной записи в него и отбрасывания вывода (и опасно!))
Да, это будет ломать вещи захватывающими и интересными способами.
Проблема в том, что Unix-подобные системы обычно выделяют файловые дескрипторы последовательно. Когда программе нужен новый дескриптор файла (т.е. они вызывают open()
, socket()
, и любую другую функцию, которая выделяет fd) ядро найдет «свободный» дескриптор с наименьшим номером и передаст его.
Теперь представьте, если хотите, что вы закрыли fd 2 (stderr). Затем что-то в процессе требует дескриптора файла (следующего открытого файла). Ядро ищет свободный fd, видит, что fd 2 не используется, и возвращает его программе.
Теперь представьте, что что-то еще в программе хочет записать в stderr. Он слепо пишет в fd 2, потому что там живет stderr. Но сейчас это не так. Если ты счастливый, fd 2 был открыт только для чтения, и при записи возникает ошибка. Все предполагают, что запись в stderr всегда будет успешной, так что это будет весело. По крайней мере, не менее вероятно, что fd предназначен для чтения-записи (пять из шести fopen
(2) режимы разрешены для записи - r+
, a
, a+
, w
, или w+
), а сообщение, которое должно было быть отправлено на stderr, только что попало в кто знает где.
Что еще более интересно, * файловые дескрипторы наследуются fork()
. Что означает, что каждый дочерний процесс также будет иметь возможность рисовать где-нибудь неожиданно. Хуже того, даже «безопасные» стратегии разветвления, например, когда все ФД закрываются раньше exec
, как правило, не касайтесь fds 0, 1 или 2. Таким образом, ваша небольшая поломка почти наверняка переживет обычные стратегии, предназначенные для предотвращения сбоя через границы процесса.
Вы можете сказать: «Я никогда не буду использовать библиотеку, которая записывает в stderr, и я буду осторожен, чтобы никогда не писать в stderr сам». На это мне нужно сказать две вещи:
Друзья не позволяют друзьям закрывать stderr. Вылезай. капает микрофон
Это может быть очень-очень плохим и вести к неопределенному поведению. Проверьте мой старый вопрос: Репликация MySQL завершается после ротации binlog.
Мы закрыли fd 2 для демона mysql, а справочное сообщение было записано в binlog.info. Это нарушило репликацию главный-подчиненный.