Inicie a aplicação (GUI) na montagem de qualquer dispositivo USB

2

Estou executando o Ubuntu-gnome 16.04 LTS 4.4.0-62-genérico.

Gostaria de fazer o seguinte: Executar ou ...

  • (a) um aplicativo ( GUI ) [/path/to/my_app.desktop]
  • ou (b) um script interativo em um terminal [por exemplo: $ gnome-terminal -x /path/to/script.sh]

... sempre que uma montagem de qualquer dispositivo (USB) for reconhecida.

A execução no servidor X do usuário parece obrigatória, já que a entrada variada do usuário é necessária em resposta ao aplicativo / script em execução; não pode simplesmente correr em segundo plano.

Nos últimos dois dias, fiz uma extensa pesquisa e experimentei os dois, udev-rules e systemd.services . O meu problema recorrente é que qualquer uma das abordagens anteriores requer autenticação X. Embora haja maneiras (complicadas) de fazer a autenticação acontecer, não gosto da ideia de violar a segurança do sistema inato exportando as variáveis $ XAUTHORITY da raiz para a sessão do usuário ...

Suponho que deveria haver uma maneira alternativa de fazer o seguinte acontecer:

  1. detecta quando / se um novo dispositivo (USB) foi montado
  2. iniciar um aplicativo / script (no terminal) com privilégios de USUÁRIO na área de trabalho do usuário (por exemplo, Xsession do usuário?)
  3. (opcional: passar o nome de usuário ligado como uma variável)

(criação de arquivos .config específicos de montagem ?; org.gnome.desktop.media-handling ?; autostart-script observando / home / $ USERNAME / media.mounts ?; editando / etc / fstab; ...? )

Qualquer sugestão seria muito apreciada.

    
por brunuser 15.02.2017 / 23:08

1 resposta

2

(Resposta antiga, nova resposta mais abaixo)

Execute um script ou comando para executar sempre que uma unidade USB for conectada

Se, por qualquer motivo, você não quiser usar as regras udev ou algo mais complicado, use o script abaixo.

Simplesmente executar o script, com o seu comando para ser executado como argumento, fará o trabalho.

O script:

#!/usr/bin/env python3
import subprocess
import time
import sys

cmd = " ".join(sys.argv[1:])

def get_mountedlist():
    return [(item.split()[0].replace("├─", "").replace("└─", ""),
             item[item.find("/"):]) for item in subprocess.check_output(
            ["/bin/bash", "-c", "lsblk"]).decode("utf-8").split("\n") if "/" in item]

def identify(disk):
    command = "find /dev/disk -ls | grep /"+disk
    return "usb" in subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")

mounted1 = get_mountedlist()
while True:
    time.sleep(4)
    mounted2 = get_mountedlist()
    if [d for d in mounted2 if all([not d in mounted1, d != "/", identify(d[0]) == True])]:
        subprocess.Popen(["/bin/bash", "-c", cmd])
    mounted1 = mounted2

Para usar

  1. Copie o script em um arquivo vazio, salve-o como run_usbactions.py
  2. Teste - execute o script por (por exemplo) o comando:

    python3 /path/to/run_usbactions.py <command_to_run> <optional_args>
    

    No meu teste, usei por exemplo:

    python3 /path/to/run_usbactions.py gedit file
    

    para abrir file com o gedit quando uma unidade USB estiver conectada.

  3. Se tudo funcionar bem, adicione-o aos aplicativos de inicialização: Dash > Aplicativos de inicialização > Adicionar. Adicione o comando:

    python3 /path/to/run_usbactions.py <command_to_run> <optional_args>
    

Explicação

  • Uma vez por quatro segundos, na função get_mountedlist() , o script lê a saída de lsblk .

  • No caso de partições adicionais ou dispositivos serem montados, a saída de (por exemplo) o comando:

    find /dev/disk -ls | grep sdc1
    

    incluirá a string usb e identificará a unidade montada como uma unidade usb.
    Olhando agora, eu poderia muito bem substituí-lo por uma maneira mais "pythonic" de fazê-lo, em vez de uma chamada de sistema, mas desde que eu copiei de um script antigo, eu não o fiz (ainda).

  • subseqüentemente, se a nova unidade for um usb, o comando (+ possíveis argumentos), conforme definido em " ".join(sys.argv[1:]) , será executado.



EDITAR

(29 de dezembro de 2017)

Usando o pyudev

Desde que eu "conheci" a pyudev, achei que deveria compartilhar a maior simplificação e a operação mais clara que ela traz. Um script simples para executar qualquer ação ao inserir um dispositivo usb torna-se:

#!/usr/bin/env python3
import pyudev
import subprocess
import sys

cmd = " ".join(sys.argv[1:])

monitor = pyudev.Monitor.from_netlink(pyudev.Context())
monitor.filter_by('block')

for device in iter(monitor.poll, None):
    if all([
        device['ACTION'] == "add", 'ID_FS_TYPE' in device,
        device['ID_USB_DRIVER'] == "usb-storage",
        ]):
        print("added", device.get('ID_FS_LABEL'))
        subprocess.Popen(["/bin/bash", "-c", cmd])

Uso

Certifique-se de que pyudev esteja instalado:

sudo apt install python3-pyudev

Mais instruções são exatamente semelhantes.

    
por Jacob Vlijm 16.02.2017 / 07:13