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”.

Note que estes arquivos só existem em distribuições que realmente utilizam o hotplug. Atualmente, está havendo uma espécie de movimento migratório em relação ao udev (que abordo a seguir). Embora o udev possa conviver com os scripts do
hotplug, muitas distribuições preferem realmente eliminá-lo, mantendo apenas o udev. Quase todas as regras do hotplug podem ser reescritas usando funções do udev, mas é interessante entender os dois sistemas, para que você possa utilizar um sistema ou
outro de acordo com o sistema usado.

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

usb-storage 0x000f 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 MP3Player, 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 a que deseja 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 exceçõ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 executá-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 “/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.

É 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 comandos 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 usada, é 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, 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:

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 é 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 do 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.

Ver Mais

Esta postagem foi modificada pela última vez em 28/09/2010 19:19

Postagem relacionada