我在 SO 中看到了如何将 STDIN、STDOUT、STDERR 重定向到 C 中的 /dev/null。这是在守护进程启动期间完成的。但是,为什么这对于正确启动 unix/linux 守护进程是必要的?
奖金问题:
如果STDOUT
关闭并使用文件描述符而不重新打开会发生什么?
我在 SO 中看到了如何将 STDIN、STDOUT、STDERR 重定向到 C 中的 /dev/null。这是在守护进程启动期间完成的。但是,为什么这对于正确启动 unix/linux 守护进程是必要的?
奖金问题:
如果STDOUT
关闭并使用文件描述符而不重新打开会发生什么?
stdin
,stdout
并stderr
关闭,以便守护进程可以成功地从它启动的 tty 中分离出来,并且守护进程(或其子进程)在运行时不会写入 tty。
如果您尝试从已关闭的文件描述符中读取/写入,则操作将失败并errno
设置为EBADF
(“fildes 不是为读取而打开的有效文件或套接字描述符”)。除此之外,不会发生任何不愉快的事情。
你不应该。正确启动 unix/linux 守护程序不是必需的。始终将您的日志消息写入stderr
.
errno
EBADF
如果使用关闭的文件描述符,则设置为,操作将失败。
不要在程序内部守护程序。使用守护程序管理器对其进行守护。(记得吗?做一件事,把它做好。)
无论您编写什么程序,请始终登录到stderr
. 这样做有以下优点,我引用Jonathan de Boyne Pollard的话:
- 因此,您的守护程序的日志输出将自动与其他守护程序的日志输出完全分开。
- 您根本不需要 chroot() 监狱中的任何额外文件。
- 日志数据不会丢失,并且会按照它们生成的顺序记录。
- 其他程序/人将无法在输出中插入欺骗消息。
重定向stderr
到/dev/null
将使系统管理员更难将您的日志聚合到他们的系统中。你可以通过以下方式激怒他们,我引用Chris Jester Yang的话:
- 坚持使用 syslog,不提供任何选项来记录到标准错误或标准输出。
- 可以肯定的是,显式关闭文件描述符 1 和 2,或将它们重定向到 /dev/null。