Escrevendo para um arquivo de um comando RUN do udev

1

Estou trabalhando na criação de um conjunto de regras do udev que grava em um arquivo de log toda vez que uma determinada unidade USB é inserida. Meu conjunto de regras, armazenado em /etc/udev/rules.d /99-log-USB-drive.rules , contém atualmente o seguinte:

# Skip if not the expected USB drive
ENV{ID_FS_UUID}!="SOMEUUID", GOTO="end"

# Try different ways of interacting with the file system
ACTION=="add", RUN+="/usr/bin/touch /home/myusername/udevtest.txt"
ACTION=="add", RUN+="/bin/chmod 664 /home/myusername/udevtest.txt"
ACTION=="add", RUN+="/bin/echo 1 | /usr/bin/tee /home/myusername/udevtest.txt"
ACTION=="add", RUN+="/bin/echo 2 >> /home/myusername/udevtest.txt"

# Exit
LABEL="end"

Os comandos touch e chmod funcionam como esperado, mas quando tento gravar no arquivo, não recebo nada. Ativando a depuração do udev usando

udevadm control --log-priority=debug

processa a seguinte saída em /var/log/syslog :

Dec  3 18:00:49 Hostname systemd-udevd[9629]: starting '/bin/echo 1 | /usr/bin/tee /home/myusername/udevtest.txt'
Dec  3 18:00:49 Hostname systemd-udevd[9612]: '/bin/echo 1 | /usr/bin/tee /home/myusername/udevtest.txt'(out) '1 | /usr/bin/tee /home/myusername/udevtest.txt'
Dec  3 18:00:49 Hostname systemd-udevd[9612]: Process '/bin/echo 1 | /usr/bin/tee /home/myusername/udevtest.txt' succeeded.
Dec  3 18:00:49 Hostname systemd-udevd[9630]: starting '/bin/echo 2 >> /home/myusername/udevtest.txt'
Dec  3 18:00:49 Hostname systemd-udevd[9612]: '/bin/echo 2 >> /home/myusername/udevtest.txt'(out) '2 >> /home/myusername/udevtest.txt'
Dec  3 18:00:49 Hostname systemd-udevd[9612]: Process '/bin/echo 2 >> /home/myusername/udevtest.txt' succeeded.

após a inserção da unidade USB. Portanto, os comandos são bem-sucedidos, mas a saída não é gravada no arquivo por algum motivo que não vejo. Esta pergunta indica que a gravação em arquivos deve funcionar.

Adendo

Um dos requisitos para este projeto é que eu precise ser capaz de gravar asteriscos ( * ) no arquivo. Usando as informações da excelente resposta de @Kamil Maciorowski, posso escrever no arquivo, mas não consigo impedir que o shell expanda o asterisco.

ACTION=="add", RUN+="/bin/sh -c 'echo * >> /home/myusername/udevtest.txt'"

escreve uma listagem do conteúdo da pasta raiz no arquivo após a inserção da unidade USB.

ACTION=="add", RUN+="/bin/sh -c 'echo "*" >> /home/myusername/udevtest.txt'"

não escreve nada no arquivo e processa a seguinte saída em /var/log/syslog :

Jan  1 12:26:45 Hostname systemd-udevd[12359]: starting '/bin/sh -c 'echo '
Jan  1 12:26:45 Hostname systemd-udevd[12346]: '/bin/sh -c 'echo '(out) ''
Jan  1 12:26:45 Hostname systemd-udevd[12346]: Process '/bin/sh -c 'echo ' succeeded.

enquanto

ACTION=="add", RUN+="/bin/sh -c 'echo '*' >> /home/myusername/udevtest.txt'"

também não grava nada no arquivo e processa a seguinte saída em /var/log/syslog :

Jan  1 12:30:48 Hostname systemd-udevd[12477]: starting '/bin/sh -c 'echo '*' >> /home/myusername/udevtest.txt''
Jan  1 12:30:48 Hostname systemd-udevd[12464]: '/bin/sh -c 'echo '*' >> /home/myusername/udevtest.txt''(out) ''
Jan  1 12:30:48 Hostname systemd-udevd[12464]: Process '/bin/sh -c 'echo '*' >> /home/myusername/udevtest.txt'' succeeded.
    
por fuumind 30.11.2017 / 15:50

3 respostas

1

Operadores como | , >> etc. significam algo dentro de um shell, mas quando o único /bin/echo 1 | … é executado, não há shell e | é apenas outro argumento para echo .

Para usar esses operadores, você precisa iniciar um shell que os analisará. Isso deve funcionar:

…
ACTION=="add", RUN+="/bin/sh -c 'echo 1 | /usr/bin/tee /home/myusername/udevtest.txt'"
ACTION=="add", RUN+="/bin/sh -c 'echo 2 >> /home/myusername/udevtest.txt'"
…

Aqui escolhi echo (shell builtin) sobre /bin/echo .

Alternativamente você pode reunir alguns comandos (ou todos eles) em um único shell script (com um shebang apropriado) e executar apenas o script a partir do conjunto de regras. Seria como:

#!/bin/sh

logfile="/home/myusername/udevtest.txt"

# /usr/bin should be in the defalut $PATH,
# so you probably don't need full paths to executables here

touch "$logfile"
chmod 664 "$logfile"
echo 1 | tee "$logfile"
echo 2 >> "$logfile"

Não se esqueça de tornar o script executável. Então, no seu conjunto de regras:

…
ACTION=="add", RUN+="/path/to/the/script"
…
    
por 20.12.2017 / 14:18
0

Quando o udevd começa a rodar, o rootfs ainda é montado com opções de somente leitura. Então você não pode mudar nada para um arquivo com a chave de execução do udev.

Aqui estão os processos de inicialização. init - > montar o sistema de arquivos virtual do kernel (etc. / run /) - > o udev em execução - > monte tudo (/ etc / fstab)

    
por 20.12.2017 / 07:54
0

Respondendo ao adendo da minha própria pergunta: Escapando o asterisco funciona.

ACTION=="add", RUN+="/bin/sh -c 'echo \* >> /home/myusername/udevtest.txt'"

escreve um asterisco no arquivo.

    
por 01.01.2018 / 12:57