4

I have an OLED screen on my laptop that I have configured to show status information. The current driver I have installed in Linux for it is able to display messages by sending them to a script as an argument separated by spaces.

Example: the command /opt/asusg50oled/utils/notify.sh Hi Everybody "Hello World" displays on the oled screen:

Hi
Everybody
Hello World

If another message is sent before the old ones disappear and it reverts to status info, it pushes off the top message. Example: less than 30 seconds after the previous example, /opt/asusg50oled/utils/notify.sh "Bananas have potassium" is executed:

Everybody
Hello World
Bananas have potassium

What I want to do is have kernel messages (the kind you see by running dmesg) forwarded to this script. For example, when I insert a USB drive, the following information would show on the OLED screen as they're logged:

[ 1283.200150] usb 2-4: new high speed USB device using ehci_hcd and address 4
[ 1283.353322] scsi9 : usb-storage 2-4:1.0
[ 1284.351366] scsi 9:0:0:0: Direct-Access     SanDisk  Cruzer           1.03 PQ: 0 ANSI: 2
[ 1284.352697] sd 9:0:0:0: Attached scsi generic sg4 type 0
[ 1284.355669] sd 9:0:0:0: [sdd] 31266816 512-byte logical blocks: (16.0 GB/14.9 GiB)
[ 1284.357032] sd 9:0:0:0: [sdd] Write Protect is off
[ 1284.357041] sd 9:0:0:0: [sdd] Mode Sense: 03 00 00 00
[ 1284.357047] sd 9:0:0:0: [sdd] Assuming drive cache: write through
[ 1284.364356] sd 9:0:0:0: [sdd] Assuming drive cache: write through
[ 1284.364371]  sdd: sdd1
[ 1284.371656] sd 9:0:0:0: [sdd] Assuming drive cache: write through
[ 1284.371666] sd 9:0:0:0: [sdd] Attached SCSI removable disk

Note that given the limited width of the screen, stripping the timestamps would also be useful. So at the end of the logging, the screen would show for about 30 seconds:

  sdd: sdd1
 sd 9:0:0:0: [sdd] Assuming drive cache: write through
 sd 9:0:0:0: [sdd] Attached SCSI removable disk

So, to clarify, I want kernel messages to be sent live by executing /opt/asusg50oled/utils/notify.sh "$MESSAGE"

I can throw in filters to weed out anything I don't want to see later, I just want to know how to do the parts mentioned above. How can I do this?

Edit

As Ciclamino suggested, I added the following line to my /etc/rsyslog.conf file:

kern.*  ^/opt/asusg50oled/utils/notify.sh

This almost worked, but the formatting resulted in the OLED just showing the date, hostname, and the word 'kernel' before running out of room. After a little digging, I figured out the following:

$template OLEDformat,"%msg%0
kern.*  ^/opt/asusg50oled/utils/notify.sh;OLEDformat

This is almost there, but again, I run out of room because of some sort of timestamp.. example display:

[ 4477.993774] sd 11:0:0:0: [sdb] At

I want to get rid of the bracketed numbers so I'm left with

sd 11:0:0:0: [sdb] Attached SCSI rem

Still not perfect but the best I'll get with the size of the screen. It would be even better if it would split it at 36 characters so I can have something like the following:

sd 11:0:0:0: [sdb] Attached SCSI rem
ovable disk

SOLVED

I am accepting Ciclamino's answer, as it got me to where I needed to be. Here's what I ended up doing:

I created and added execute bit to shell script /opt/asusg50oled/utils/notify-kern.sh containing

#!/bin/bash
cd `dirname $0`
stringA=$1
stringB=${stringA#\[*\]}
stringC=${stringB:0:36}
stringD=${stringB:36}
./notify.sh "$stringC" "$stringD"

Then I appended to /etc/rsyslog.conf

## output kernel messages to OLED
$template OLEDformat,"%msg%"
kern.*  ^/opt/asusg50oled/utils/notify-kern.sh;OLEDformat

Finally, I restarted rsyslog with sudo service rsyslog restart.

3 Answers 3

3

You can use syslog to catch kernel messages and pipe them to a command. The syntax will be a little different for the various different implementations of syslogd. Here's an example of how to do it with rsyslog (in /etc/rsyslog.conf):

kern.*  ^/opt/asusg50oled/utils/notify.sh
4
  • This looks like exactly what I want to do. I'll check to see if it works properly next time I'm in Linux.
    – TuxRug
    Commented Apr 14, 2011 at 0:11
  • This is VERY close... Right now I get the date, hostname, the word kernel, a colon, and then the OLED runs out of space... I'm going to see if I can figure out how to shave that off... I'm sure I can write an intermediate script to pull out the : and everything before it.
    – TuxRug
    Commented Apr 14, 2011 at 17:21
  • Looks like I need a little more help... how do I get it to shave off everything up to and including the first ':'? Right now I'm getting Apr 14 11:36:35 TuxTop-III-LM kernel: and then I run out of space.
    – TuxRug
    Commented Apr 14, 2011 at 17:37
  • Ok I found something that got me even closer... I used a template (see edits to the question).. Still not quite there.
    – TuxRug
    Commented Apr 14, 2011 at 17:50
3

here is a quick and dirty solution:

tail -n 0 -f /var/log/messages | while read -r MESSAGE; do
  /opt/asusg50oled/utils/notify.sh "$MESSAGE"
done
2
  • This doesn't push them as they happen, though, and I only want the ones that just fired to display. I want something that catches the messages as they are produced.
    – TuxRug
    Commented Apr 13, 2011 at 20:50
  • 1
    @TuxRug I messed up. It should have been /var/log/messages instead of /var/log/dmesg. I updated my answer. Also, with tail -n 0 you only get the newestest messages after invocation of the command.
    – Lesmana
    Commented Apr 13, 2011 at 21:12
0

You can repeatedly read the output of /proc/kmsg using tail or whatever method you prefer.

I think you need to be root to do so, however.

1
  • Unfortunately, this would infinitely print the messages over and over again. I want the command fired once per message so that the message will appear for 30 second. Once 30 seconds have gone by without a new message, it will revert to the normal status display.
    – TuxRug
    Commented Apr 13, 2011 at 20:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .