是否可以动态地将发送到的所有数据重定向/dev/console
到其他内容(例如 - 到/dev/null
,/dev/tty9
甚至/dev/null
)?
当然可以静态地通过console=XXX
内核启动参数(或在单个程序的情况下标准管道重定向)。问题是我需要根据来自外部设备的数据动态地执行此操作(对于所有进行输出的程序)。
有什么建议么?
答案1
我能想到几个选项,它们的有效性取决于事情如何进入“控制台”。
对于源自内核的消息,最简单的方法是dmesg -n 1
禁用(几乎所有)控制台消息,并使用 syslogd/klogd 提取并记录它们或转发它们。无论控制台日志级别如何,所有内核消息仍会被记录并可通过/proc/kmsg
(或)访问。sys_syslog()
对此的一种变体是引导内核以quiet
抑制printk()
输出,并仅依赖 syslogd/klogd 来处理内核消息。
一个更冒险和更全面的选择是使用控制台模块,这些更常用于 VM 来宾,以便 VM 主机可以直接访问来宾控制台。有两种类型, 这系统驱动程序(例如 x86 PC 上的“VGA”,内核“console=”选项);模块化驱动器它可以根据需要加载和卸载,并且可以接管系统驱动程序。一个可能有用的驱动程序是网络控制台,虽然它很容易加载和卸载(它既可以用作系统驱动程序也可以用作模块化驱动程序),但有两个缺点:
- 事实并非如此
take_over_console()
,所以一切仍然会转到原始控制台 - 它仅通过以太网记录(不支持环回)
您也许可以使用“虚拟”控制台和上述选项之一执行一些有用的操作。netcat
或者socat
为网络控制台制作良好的“客户端”:
modprobe netconsole "[email protected]/eth0,[email protected]/ff:ff:ff:ff:ff:ff"
socat UDP4-LISTEN:55514 -
如果您对从各个系统服务捕获控制台输出更感兴趣,那么我认为没有无需修改脚本的简单方法。
执行此操作的不简单(可能也不好)的方法包括使用 LD_PRELOAD 劫持生成输出的重定向函数,或添加一些_init
代码来修改默认文件描述符。或者更糟糕:附加调试器并且操作打开的文件描述符。/etc/ld.so.preload
将是实现第一个选项的简单(如果黑客且有点令人讨厌)的方法。
如果我想监视守护进程的控制台输出,我可能会修改启动脚本以在screen
会话中运行它们,也许像这样。