我的笔记本电脑上有一个 OLED 屏幕,我已将其配置为显示状态信息。我在 Linux 中为其安装的当前驱动程序能够通过将消息作为以空格分隔的参数发送到脚本来显示消息。
/opt/asusg50oled/utils/notify.sh Hi Everybody "Hello World"
例:在oled屏幕上显示命令:
Hi
Everybody
Hello World
如果在旧消息消失之前发送了另一条消息,并且该消息恢复为状态信息,则会推迟顶部消息。示例:在上一个示例执行后不到 30 秒,/opt/asusg50oled/utils/notify.sh "Bananas have potassium"
执行:
Everybody
Hello World
Bananas have potassium
我想要做的是将内核消息(通过运行看到的那种dmesg
)转发到此脚本。例如,当我插入 USB 驱动器时,OLED 屏幕上将显示以下信息:
[ 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
请注意,由于屏幕宽度有限,删除时间戳也会很有用。因此,在记录结束时,屏幕将显示约 30 秒:
sdd: sdd1
sd 9:0:0:0: [sdd] Assuming drive cache: write through
sd 9:0:0:0: [sdd] Attached SCSI removable disk
因此,澄清一下,我希望通过执行以下代码来实时发送内核消息/opt/asusg50oled/utils/notify.sh "$MESSAGE"
我可以添加过滤器来过滤掉我不想看到的内容,我只是想知道如何完成上述部分。我该怎么做?
编辑
按照 Ciclamino 的建议,我在 /etc/rsyslog.conf 文件中添加了以下行:
kern.* ^/opt/asusg50oled/utils/notify.sh
这几乎成功了,但格式化导致 OLED 只显示日期、主机名和单词“内核”,然后空间就用完了。经过一番挖掘,我发现了以下内容:
$template OLEDformat,"%msg%0
kern.* ^/opt/asusg50oled/utils/notify.sh;OLEDformat
这几乎已经完成了,但是由于某种时间戳,我再次用完了空间。示例显示:
[ 4477.993774] sd 11:0:0:0: [sdb] At
我想去掉括号里的数字,这样就剩下
sd 11:0:0:0: [sdb] Attached SCSI rem
虽然还不够完美,但对于这个屏幕尺寸来说,这已经是最好的了。如果能以 36 个字符为单位进行拆分,效果会更好,这样我就可以得到类似下面的内容:
sd 11:0:0:0: [sdb] Attached SCSI rem
ovable disk
解决了
我接受 Ciclamino 的回答,因为它让我找到了我需要的答案。以下是我最终做的事情:
/opt/asusg50oled/utils/notify-kern.sh
我创建并添加了执行位到包含以下内容的shell 脚本
#!/bin/bash
cd `dirname $0`
stringA=$1
stringB=${stringA#\[*\]}
stringC=${stringB:0:36}
stringD=${stringB:36}
./notify.sh "$stringC" "$stringD"
然后我附加到 /etc/rsyslog.conf
## output kernel messages to OLED
$template OLEDformat,"%msg%"
kern.* ^/opt/asusg50oled/utils/notify-kern.sh;OLEDformat
最后,我用 重新启动了 rsyslog sudo service rsyslog restart
。
答案1
您可以使用 syslog 来捕获内核消息并将它们传送到命令。对于 syslogd 的各种不同实现,语法会略有不同。以下是如何使用 rsyslog 执行此操作的示例(在 /etc/rsyslog.conf 中):
kern.* ^/opt/asusg50oled/utils/notify.sh
答案2
这是一个快速而肮脏的解决方案:
tail -n 0 -f /var/log/messages | while read -r MESSAGE; do
/opt/asusg50oled/utils/notify.sh "$MESSAGE"
done
答案3
/proc/kmsg
您可以使用tail
或任何您喜欢的方法反复阅读输出。
我思考然而,您需要以 root 身份执行此操作。