Criando scripts para o hotplug

O hotplug se orienta com base em diversos arquivos organizados dentro do diretório “/etc/hotplug” para carregar os módulos adequados conforme novos dispositivos são plugados. Para os dispositivos USB, por
exemplo, são usados os arquivos “usb.distmap” (que contém um conjunto de regras pré-definidas) e o arquivo “usb.usermap” permite definir regras adicionais. Em muitas distribuições o segundo arquivo não existe por padrão,
mas basta criá-lo usando o comando “touch /etc/hotplug/usb.usermap

Ambos os arquivos são formados por um conjunto de regras, como a abaixo:

usb-storage 0x000 f 0x03ee 0x0000 0x0000 0x0245 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000

O primeiro campo “usb-storage” indica um script que será executado (ou um módulo que será carregado) quando um dispositivo que se encaixa nas regras descritas nos campos seguintes for encontrado.

A maioria das distribuições traz um conjunto de scripts dentro da pasta “/etc/hotplug/usb/“, que são executados quando determinados dispositivos são plugados. Isso faz com que seja criado um ícone no desktop
ao ser plugado um pendrive e outras ações do gênero.

Um dos recursos mais interessantes do hotplug é que você pode criar ações adicionais, fazendo com que sejam executadas ações diversas quando você plugar dispositivos USB especificados. Você pode fazer com que seja executado
um script de backup automaticamente quando plugar seu HD USB, fazer com que o Amarok ou outro aplicativo seja aberto quando plugar seu MP3 Player, fazer com que um determinado game seja aberto ao plugar o joystick, ou qualquer outra coisa que tenha em
mente.

O primeiro passo é plugar o dispositivo e rodar o comando “lsusb“. Procure a linha com a identificação do dispositivo que quer atribuir a ação, como em:

Bus 003 Device 023: ID 05e3:0702 Genesys Logic, Inc. USB 2.0 IDE Adapter

Aqui estou usando uma gaveta de HD, um adaptador que permite ligar um HD de notebook direto na porta USB, fazendo com que ele seja reconhecido como um pendrive. O mais importante é o “ID 05e3:0702”, que contém o código do
dispositivo, que usaremos na regra. O primeiro número (05e3) é o código do fabricante, enquanto o “0702” é o modelo.

Abra os arquivos “/etc/hotplug/usb.distmap” e “/etc/hotplug/usb.usermap“. Dê uma olhada nos exemplos incluídos no “usb.distmap” e copie algum deles para o “usb.usermap”, como exemplo.

Como estou fazendo um script para uma gaveta de HD, vou dar um exemplo de como fazer com que seja executado um script que faz automaticamente backup de algumas pastas, sempre que ela é plugada.

As linhas adicionadas no “usb.usermap” seguem uma sintaxe especial, com vários campos. Não é prático escrever tudo manualmente, justamente por isso copiamos uma linha do outro arquivo e vamos apenas modificá-la.

Como disse, o primeiro campo indica o script (dentro da pasta “/etc/hotplug/usb/“) que será executado. No exemplo, estou indicando o script “gaveta”. O terceiro e o quarto campo contém os números de
identificação do dispositivo, os dois números que apareceram no lsusb. É através deles que o hotplug saberá diferenciar a gaveta de outros dispositivos USB. Note que é necessário adicionar um “0x” antes de cada um dos dois números, como em:

gaveta 0x0003 0x05e3 0x0702 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000

O segundo campo (chamado “match_flags“) indica como a regra será aplicada. O “0x0003” é o código “padrão” para regras personalizadas, que diz que a regra se aplica apenas a dispositivos com os dois códigos
de identificação. A regra vai ser disparada se você plugar uma outra gaveta, exatamente igual à primeira, mas não se plugar um pendrive, por exemplo.

Existem outros códigos, menos usados, que permitem definir regras mais gerais. Usando “0x0000” você cria uma regra que se aplica a qualquer dispositivo USB plugado, independentemente do que seja e o “0x000f”, que permite
definir excessões, ou seja, dispositivos específicos que não disparam uma regra mais genérica. Mexer com estes códigos permite criar regras mais abrangentes (como as usadas no usb.distmap), que permitem coisas como, por exemplo, disparar uma ação quando
qualquer pendrive ou scanner é conectado (independente do fabricante). Mas, trabalhar com eles é um pouco mais complicado, pois você precisa conhecer bem os códigos de identificação dos dispositivos e as regras que podem ser usadas, e ambas as coisas não
são bem documentadas.

Para manter as coisas simples, vou me concentrar na criação de regras específicas, usando sempre o ” 0x0003″ no segundo campo.

Na linha do exemplo, especifiquei que o script “/etc/hotplug/usb/gaveta” deve ser executado sempre que o dispositivo com o código “0x05e3 0x0702” for plugado. O arquivo é um shell script normal, com os
comandos que você quer que sejam executados.

Este seria um exemplo de script simples, que faria backup da pasta “/mnt/hda6/ARQUIVOS/“:

#!/bin/sh

umount /mnt/sda1; sleep 1
mount /dev/sda1 /mnt/sda1
montado=`mount | grep /mnt/sda1`

if [ -z “$montado” ]; then
exit 2
else
rsync -av /mnt/hda6/ARQUIVOS/ /mnt/sda1/ARQUIVOS
sync
umount /mnt/sda1
fi

touch /tmp/deu_certo

Por segurança, o script primeiro tenta montar a partição de dados da gaveta e roda o comando de backup apenas se ela realmente foi montada. No exemplo estou usando o “rsync“, pois a idéia é fazer um backup
incremental, rápido. O comando “sync” sincroniza os buffers de dados, gravando qualquer informação não salva. É importante executa-lo sempre antes de desplugar qualquer dispositivo de dados, caso contrário você quase sempre vai perder as
últimas alterações.

Da forma como está, o único feedback de que o script foi realmente executado, é a criação do arquivo “touch /tmp/deu_certo“. Mesmo que o script seja apenas para uso pessoal, seria interessante melhorar o
sistema de feedback, para que você saiba quando o backup terminou, por exemplo.

É fácil fazer perguntas e mostrar mensagens de aviso usando o kdialog. O maior problema é que os scripts executados pelo hotplug são executados num shell separado, fora do modo gráfico. É como se você pressionasse
Ctrl+Alt+F1 para mudar para o modo texto e executasse os comando a partir de lá. Isso faz com que, originalmente, nenhum programa gráfico possa ser usado.

Para resolver isso, adicione o comando “export DISPLAY=:0” no início do script. Isto explica que ele deve usar a tela principal do X para exibir qualquer programa gráfico chamado adiante.

Dependendo da distribuição que estiver usando, é necessário também copiar o arquivo “.Xauthority” de dentro do home do usuário que está usando o X para dentro do “/root“, de forma que o root
possa usar a seção aberta.

Se você usa sempre o mesmo usuário, isso não é problema, basta incluir o comando “cp -f /home/usuario/.Xauthority /root“. Mas, se o script vai ser usado por outras pessoas, é necessário torná-lo
mais “inteligente”, fazê-lo descobrir sozinho qual é o usuário logado e copiar o arquivo.

Ao usar o KDE, é sempre criado um arquivo “/tpm/kde-usuario“. Se usarmos o comando “ls /tmp/“, deixando só as linhas que contiverem “kde-” (removendo um eventual
“kde-root”) e, em seguida remover o “kde-” da linha que vai sobrar, ficaremos só com o nome do usuário.

usuario=`ls /tmp/ | grep “kde” | sed -s ‘/root/D’ | cut -f “2” -d “-“`

A limitação aqui é que o script só vai funcionar adequadamente quando houver apenas um usuário do KDE. Para o caso de máquinas que aceitam logins remotos, como um servidor LTSP, por exemplo, eu sugiro que você use use a
saída do comando “w” (que lista os usuários remotos), para deixar na lista apenas o usuário local.

Adicionando a função, nosso script ficaria:

#!/bin/sh

usuario=`ls /tmp/ | grep “kde” | sed -s ‘/root/D’ | cut -f “2” -d “-“`
cp -f /home/$usuario/.Xauthority /root/
export DISPLAY=:0

kdialog –yesno “Fazer o backup?”
resposta=$?

if [ “$resposta” = “0” ]; then
umount /mnt/sda1; sleep 1
mount /dev/sda1 /mnt/sda1
montado=`mount | grep /mnt/sda1`

if [ -z “$montado” ]; then
exit 2
else
rsync -av /mnt/hda6/ARQUIVOS/ /mnt/sda1/ARQUIVOS
sync
umount /mnt/sda1
kdialog –msgbox “Backup completo”
fi
fi

Veja que adicionei também duas caixas de diálogo. A primeira confirma se você quer fazer o backup e a segunda avisa quando ele ele é concluído.

Seguindo esta idéia de abrir aplicativos gráficos ao plugar dispositivos USB, podemos criar uma regra que abre o Epsxe (que você pode trocar por outro game ou emulador qualquer), sempre que um joystick USB é plugado.

Seguindo o exemplo anterior, o primeiro passo é adicionar a linha contendo o código de identificação do Joystick no arquivo “/etc/hotplug/usb.usermap“:

joypad 0x0003 0x046d 0xc20c 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000

Aqui especifiquei que será executado o script “/etc/hotplug/usb/joypad“. Dentro do script vai a função para rodar aplicativos gráficos, seguida do comando que abre o emulador:

#!/bin/sh

usuario=`ls /tmp/ | grep “kde” | sed -s ‘/root/D’ | cut -f “2” -d “-“`
cp -f /home/$usuario/.Xauthority /root/
export DISPLAY=:0

sudo -u $usuario epsxe

O comando “sudo -u $usuario epsxe” faz com que o comando seja executado pelo usuário logado, ao invés de pelo root, o que daria margem para problemas de segurança diversos. Este comando pode ser usado sempre que você quiser
abrir um programa dentro do ambiente gráfico (como, por exemplo, uma janela do konqueror mostrando os arquivos de um pendrive ou câmera), mas de forma que o programa seja executado dentro das permissões de acesso do usuário.

Sobre o Autor

Redes Sociais:

Deixe seu comentário

X