Pipe mensagens do kernel para outro processo conforme elas ocorrem

4

Eu tenho uma tela OLED no meu laptop que configurei para mostrar informações de status. O driver atual que eu instalei no Linux para ele é capaz de exibir mensagens enviando-as para um script como um argumento separado por espaços.

Exemplo: o comando /opt/asusg50oled/utils/notify.sh Hi Everybody "Hello World" é exibido na tela oled:

Hi
Everybody
Hello World

Se outra mensagem for enviada antes que as antigas desapareçam e ela retorne às informações de status, ela apagará a mensagem principal. Exemplo: menos de 30 segundos após o exemplo anterior, /opt/asusg50oled/utils/notify.sh "Bananas have potassium" é executado:

Everybody
Hello World
Bananas have potassium

O que eu quero fazer é ter mensagens do kernel (do tipo que você vê executando dmesg ) encaminhadas para este script. Por exemplo, quando insiro uma unidade USB, as seguintes informações são mostradas na tela OLED conforme elas são registradas:

[ 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

Observe que, dada a largura limitada da tela, a remoção dos timestamps também seria útil. Então, no final do registro, a tela seria exibida por cerca de 30 segundos:

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

Então, para esclarecer, eu quero que as mensagens do kernel sejam enviadas ao vivo executando /opt/asusg50oled/utils/notify.sh "$MESSAGE"

Eu posso adicionar filtros para eliminar qualquer coisa que eu não queira ver depois, só quero saber como fazer as partes mencionadas acima. Como posso fazer isso?

Editar

Como Ciclamino sugeriu, adicionei a seguinte linha ao meu arquivo /etc/rsyslog.conf:

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

Isso quase funcionou, mas a formatação resultou no OLED mostrando apenas a data, hostname e a palavra 'kernel' antes de ficar sem espaço. Depois de um pouco de escavação, descobri o seguinte:

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

Isso está quase lá, mas, novamente, eu fico sem espaço por causa de algum tipo de timestamp. Exemplo:

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

Eu quero me livrar dos números entre colchetes, então fico com

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

Ainda não é perfeito, mas o melhor que conseguirei com o tamanho da tela. Seria ainda melhor se ele fosse dividido em 36 caracteres para que eu possa ter algo como o seguinte:

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

RESOLVIDO

Estou aceitando a resposta da Ciclamino, pois ela me levou até onde eu precisava estar. Aqui está o que acabei fazendo:

Eu criei e adicionei o bit de execução ao shell script /opt/asusg50oled/utils/notify-kern.sh contendo

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

Então eu adicionei ao /etc/rsyslog.conf

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

Finalmente, reiniciei o rsyslog com sudo service rsyslog restart .

    
por TuxRug 13.04.2011 / 21:41

3 respostas

3

Você pode usar o syslog para capturar mensagens do kernel e enviá-las para um comando. A sintaxe será um pouco diferente para as várias implementações diferentes do syslogd. Aqui está um exemplo de como fazer isso com o rsyslog (em /etc/rsyslog.conf):

kern.*  ^/opt/asusg50oled/utils/notify.sh
    
por 13.04.2011 / 23:21
3

aqui está uma solução rápida e suja:

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

Você pode ler repetidamente a saída de /proc/kmsg usando tail ou qualquer método que preferir.

Eu acho que você precisa ser o root para fazer isso, no entanto.

    
por 13.04.2011 / 22:03