Is it possible to dynamically redirect all data sent to /dev/console into something else (for example - to /dev/null, /dev/tty9 or even /dev/null)?

Of course, it can be done statically via console=XXX kernel boot parameter (or standard pipe redirection in case of a single program). The problem is that I need to do it dynamically (and for all programs that do output), based on data that comes from an external device.

Any suggestions?

  • It's not common for programs to directly write to /dev/console, usually printk() or syslogd are the source. Permissions are (usually) 600 root:root. – mr.spuratic Oct 23 '13 at 21:14
  • Yes, it's /sbin/init, services and a few other programs. I just want to find a solution that does not require to modify start-up scripts (or redirect output in multiple places). Something simple and robust. – qehgt Oct 23 '13 at 22:13

There are a few options I can think of, their effectiveness depends on how things get on to "the console".

For kernel-sourced messages the simplest is to use dmesg -n 1 to disable (practically all) console messages, and use syslogd/klogd to extract and either log them or forward them. All kernel messages still get logged and are accessible via /proc/kmsg (or sys_syslog()) regardless of the console log level. A variation on this is to boot your kernel with quiet which suppresses printk() output, and rely only on syslogd/klogd to process kernel messages.

A more adventurous and comprehensive option is to use a console module, these are more commonly used in VM guests so that the VM host can access guest consoles directly. There are two types, the system driver (e.g. "VGA" on an x86 PC, the kernel "console=" option); and the modular driver which can be loaded and unloaded as needed, and may take over the system driver. One possibly useful driver is netconsole, while it's readily loadable and un-loadable (it can be used as both a system and modular driver) there are two downsides:

  • it doesn't take_over_console() so everything still goes to the original console
  • it only logs via ethernet (loopback is not supported)

You may be able to do something useful with the "dummy" console, and one of the options above. netcat or socat make good "clients" for a netconsole:

modprobe netconsole "netconsole=55514@,6667@"
socat UDP4-LISTEN:55514 -

If you're more interested in capturing console output from individual system services, then I don't think there's a simple way without script modifications.

Not-simple (and possibly not nice) ways of doing this include using LD_PRELOAD to hijack redirect functions that generate output, or to add some _init code to amend default file descriptors. Or worse: attaching with a debugger and manipulating the open file descriptors. /etc/ld.so.preload would be a simple (if hackish and slightly nasty) way of implementing the first option.

If I wanted to monitor console output for daemons, I'd probably amend the startup scripts to run them in screen sessions, perhaps like so.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.