Como executar um shellscript quando eu plugo um dispositivo USB

18

Eu quero executar um script quando eu conecto um dispositivo na minha máquina Linux. Por exemplo, execute xinput no mouse ou um backup em uma determinada unidade.

Eu tenho visto muitos artigos sobre isso, mais recentemente aqui e aqui . Mas eu simplesmente não consigo fazer isso funcionar.

Aqui estão alguns exemplos simples tentando obter pelo menos algum tipo de resposta.

/etc/udev/rules.d/test.rules

#KERNEL=="sd*", ATTRS{vendor}=="*", ATTRS{model}=="*", ATTRS{serial}=="*", RUN+="/usr/local/bin/test.sh"
#KERNEL=="sd*", ACTION=="add", "SUBSYSTEM=="usb", ATTRS{model}=="My Book 1140    ", ATTRS{serial}=="0841752394756103457194857249", RUN+="/usr/local/bin/test.sh"
#ACTION=="add", "SUBSYSTEM=="usb", RUN+="/usr/local/bin/test.sh"
#KERNEL=="sd*", ACTION=={add}, RUN+="/usr/local/bin/test.sh"
KERNEL=="sd*", RUN+="/usr/local/bin/test.sh"
KERNEL=="*", RUN+="/usr/local/bin/test.sh"

/usr/local/bin/test.sh

#!/usr/bin/env bash
echo touched >> /var/log/test.log

if [ "${ACTION}" = "add" ] && [ -f "${DEVICE}" ]
then
    echo ${DEVICE} >> /var/log/test.log
fi

A pasta de regras é assistida por inotify e deve estar ativa imediatamente. Eu continuo a repor o meu teclado, mouse, tablet, memorystick e usb-drive, mas nada. Nenhum arquivo de log foi tocado.

Agora, qual seria a maneira mais simples de saber que pelo menos alguma coisa está funcionando? É mais fácil trabalhar com algo que está funcionando do que com algo que não é.

    
por Redsandro 22.02.2013 / 16:25

3 respostas

18

Se você quiser executar o script em um dispositivo específico, poderá usar os IDs do fornecedor e do produto

  • Em /etc/udev/rules.d/test.rules :

    ATTRS{idVendor}=="152d", ATTRS{idProduct}=="2329", RUN+="/tmp/test.sh"
    
  • em test.sh :

    #! /bin/sh
    
    env >>/tmp/test.log
    file "/sys${DEVPATH}" >>/tmp/test.log
    
    if [ "${ACTION}" = add -a -d "/sys${DEVPATH}" ]; then
    echo "add ${DEVPATH}" >>/tmp/test.log
    fi
    

Com env , você pode ver qual ambiente é definido a partir do udev e com file , você descobrirá o tipo de arquivo.

Os atributos concretos do seu dispositivo podem ser descobertos com lsusb

lsusb

...
Bus 001 Device 016: ID 152d:2329 JMicron Technology Corp. / JMicron USA Technology Corp. JM20329 SATA Bridge
...

    
por 22.02.2013 / 17:00
1

Isso não é diretamente sobre sua pergunta, mas sobre o que você está fazendo. Se você iniciar um script de backup do udev, enfrentará dois problemas principais:

  1. Seu scrpit pode ser iniciado antes que o dispositivo esteja pronto e possa ser montado, você deve manter a condição KERNEL == "sd *" se quiser usar o nó / dev para montá-lo
  2. Mais importante, se o seu scirpt levar algum tempo para ser executado (o que pode ser facilmente o caso com um script de backup), ele será eliminado logo após ser iniciado (cerca de 5s)
  3. Você enfrentará muitos problemas complicados de permissão de usuário

Meu conselho é criar um script na página inicial do usuário que ouça um canal nomeado e que seja iniciado de forma assíncrona, como:

#!/bin/bash

PIPE="/tmp/IomegaUsbPipe"
REMOTE_PATH="/path/to/mount/point"
LOCAL_PATH="/local/path/"


doSynchronization()
{
  #your backup here
}

trap "rm -f $PIPE" EXIT

#If the pipe doesn't exists, create it
if [[ ! -p $PIPE ]]; then
    mkfifo $PIPE
fi

#If the disk is already plugged on startup, do a syn
if [[ -e "$REMOTE_PATH" ]]
then
    doSynchronization
fi

#Make the permanent loop to watch the usb connection
while true
do
    if read line <$PIPE; then
        #Test the message red from the fifo
        if [[ "$line" == "connected" ]]
        then
            #The usb has been plugged, wait for disk to be mounted by KDE
            while [[ ! -e "$REMOTE_PATH" ]]
            do
                sleep 1
            done
            doSynchronization
        else
            echo "Unhandled message frome fifo : [$line]"
        fi
    fi
done
echo "Reader exiting"

Nota: eu uso o auto-mount com o kde para verificar se a pasta aparece. Você pode passar o parâmetro / dev / sd * no fifo da regra do udev e montá-lo no script. Para escrever no fifo, não esqueça que o udev não é um shell e esse redirecionamento não funciona. Seu RUN deve ser como:

EXECUTAR +="/ bin / sh -c '/ bin / echo conectado > > / tmp / IomegaUsbPipe'"

    
por 24.08.2018 / 16:09
-1

Para executar o script na inicialização quando o dispositivo USB é inserido, eu uso a solução abaixo:

Formate o pendrive ou qualquer outro armazenamento usb e dê um nome a ele ao fazer isso. Então em código% adicionar linha /etc/rc.local

ele criará um arquivo txt chamado label.txt (pode ser qualquer outro nome)

depois, novamente em /etc/rc.local, adicione mais 2 linhas:

if  grep -q USB_drive_name /home/pi/label.txt; then
sudo /home/pi/script.sh

Agora, sempre que pendrive com o nome USB_drive_name for inserido, o script será executado.

Com algumas pequenas modificações acima, a solução pode ser usada quando o sistema está ativo e em execução.

    
por 24.08.2018 / 15:24