Почему при запуске демона следует перенаправлять STDIN, STDOUT, STDERR в /dev/null?
Я видел в SO как перенаправить STDIN, STDOUT, STDERR в /dev / null в C . Это делается во время запуска демона. Но почему это необходимо для правильного запуска демона unix/linux?
Бонус-Вопрос :
что произойдет, если STDOUT
закрывается и файловый дескриптор используется без повторного открытия ?
2 ответов
stdin
, stdout
и stderr
закрыты, чтобы демон мог успешно отсоединиться от tty, из которого он был запущен, а также чтобы демон (или его дочерние процессы) не писал в tty при его запуске.
если вы попытаетесь прочитать / записать из закрытого дескриптора файла, операция завершится неудачей и errno
будет установлен в EBADF
("fildes не является допустимым дескриптором файла или сокета, открытым для чтения"). Кроме этого, ничего плохого не случится.
TL; DR
не стоит. это не надо для правильного запуска демона unix / linux. всегда пишите свои сообщения журнала stderr
.
бонус
errno
установлено значение EBADF
Если дескриптор файла, и операция будет выполнена.
резюме
не демонизируйте свою программу внутри себя. Используйте daemon manager, чтобы демонизировать его. (Помнишь? выполните одно сделай все правильно.)
какую бы программу вы ни написали, всегда входите в stderr
. Это имеет следующие преимущества, и я цитирую Джонатан де Бойн Поллард:
- выход журнала из вашего Деймона будет, как следствие, автоматически полностью отделен от выхода журнала других деймонов.
- вам не понадобятся никакие дополнительные файлы в тюрьме chroot ().
- данные журнала не будут потеряны и будут записаны в том же порядке, в котором они были созданы.
- другие программы / люди не смогут вставлять сообщения spoof в выходные данные.
перенаправления stderr
до /dev/null
будет намного сложнее для sysadmin объединить ваш журнал в свои системы. Вы можете разозлить их, сделав следующее, я цитирую Крис Шут Ян:
- настаивайте на использовании системного журнала и не предоставляйте никаких параметры для входа в стандартную ошибку или стандартный вывод.
- чтобы быть уверенным, явно закройте файловые дескрипторы 1 и 2 или перенаправьте их в /dev/null.