題 將內核消息發送到另一個進程


我的筆記本電腦上有一個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的回答,因為它讓我到了我需要的地方。這是我最終做的事情:

我創建並添加了執行位到shell腳本 /opt/asusg50oled/utils/notify-kern.sh 含

#!/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


4
2018-04-13 19:41


起源




答案:


您可以使用syslog捕獲內核消息並將它們傳遞給命令。 syslogd的各種不同實現的語法略有不同。以下是使用rsyslog(在/etc/rsyslog.conf中)執行此操作的示例:

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

3
2018-04-13 21:21



這看起來就像我想做的那樣。我下次在Linux時會檢查它是否正常工作。 - TuxRug
這非常接近......現在我得到日期,主機名,單詞內核,一個冒號,然後OLED耗盡空間...我將看看我是否可以弄清楚如何刮掉它...我確信我可以編寫一個中間腳本來提取:以及之前的所有內容。 - TuxRug
看起來我需要更多的幫助...我如何讓它剃掉一切,包括第一個':'?現在我得到了 Apr 14 11:36:35 TuxTop-III-LM kernel: 然後我的空間用完了。 - TuxRug
好吧,我找到了讓我更接近的東西......我使用了一個模板(參見問題的編輯)..仍然不是那裡。 - TuxRug


這是一個快速而骯髒的解決方案:

tail -n 0 -f /var/log/messages | while read -r MESSAGE; do
  /opt/asusg50oled/utils/notify.sh "$MESSAGE"
done

3
2018-04-13 20:12



儘管如此,這並沒有推動它們,而我只想要那些剛剛開始顯示的那些。我希望能夠在生成消息時捕獲消息。 - TuxRug
@TuxRug我搞砸了。應該是的 /var/log/messages 代替 /var/log/dmesg。我更新了我的答案。還有,用 tail -n 0 您只能在調用命令後獲取newestest消息。 - lesmana


你可以反复閱讀輸出 /proc/kmsg 運用 tail 或者你喜歡的任何方法。

一世 認為 但是,你需要成為root用戶。


0
2018-04-13 20:03



不幸的是,這會無限次地打印消息。我希望每個消息觸發一次命令,以便消息顯示30秒。一旦30秒沒有新消息,它將恢復到正常狀態顯示。 - TuxRug