Execute o script quando o monitor estiver conectado

11

Estou tentando executar um script localizado em usr/local/bin/ quando conecto um monitor externo ao meu laptop. Eu tentei adicionar uma nova regra udev , mas isso não funcionou. Eu criei um novo arquivo em /etc/udev/rules.d chamado vga-monitor-connect.rules . O conteúdo do arquivo era

SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/local/bin/panel-fix"

Eu peguei a linha de esta resposta

Após pesquisar on-line, também experimentei a seguinte regra

KERNEL=="card0", SUBSYSTEM=="drm", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/rumesh/.Xauthority", RUN+="/usr/local/bin/panel-fix"

No entanto, isso também não funcionou.

Eu executei o script manualmente e posso confirmar que ele funciona, por isso não é um problema com o meu script.

Também quero deixar claro que não sei muito sobre udev , portanto, a regra que usei pode estar errada. Se alguém souber a regra adequada para o meu problema, por favor deixe uma resposta.

Minha placa gráfica é um chipset integrado Intel GM965

    
por Rumesh 30.05.2015 / 12:29

1 resposta

7

Uma maneira alternativa de executar um comando se uma tela estiver conectada ou desconectada

Uma solução alternativa seria executar um pequeno script de segundo plano. Executando o script abaixo em segundo plano, não consegui medir nenhum aumento na carga do processador.

É uma maneira fácil e conveniente de executar um script ou qualquer outro comando sempre que uma segunda tela é conectada ou desconectada.

O script de exemplo

  • Simplesmente verifica a cada cinco segundos quantas vezes a string "connected" ocorre na saída do comando xrandr (ocupa o espaço depois de "connected" para evitar correspondências falsas com "disconnected"). Cada ocorrência representa uma tela conectada.
  • Se o número de ocorrências for alterado, uma tela foi conectada ou desconectada. A mudança é "notada" pelo script e pode ser conectada a um comando, você pode definir na seção head do script.

O script

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

#--- set both commands (connect / disconnect) below
connect_command = "gedit"
disconnect_command = ""
#---

def get(cmd): return subprocess.check_output(cmd).decode("utf-8")
# - to count the occurrenc of " connected "
def count_screens(xr): return xr.count(" connected ")
# - to run the connect / disconnect command(s)
def run_command(cmd): subprocess.Popen(["/bin/bash", "-c", cmd])

# first count
xr1 = None

while True:
    time.sleep(5)
    # second count
    xr2 = count_screens(get(["xrandr"]))
    # check if there is a change in the screen state
    if xr2 != xr1:
        print("change")
        if xr2 == 2:

            # command to run if connected (two screens)
            run_command(connect_command)
        elif xr2 == 1:
            # command to run if disconnected (one screen)
            # uncomment run_command(disconnect_command) to enable, then also comment out pass
            pass
            # run_command(disconnect_command)
    # set the second count as initial state for the next loop
    xr1 = xr2

Como usar

  1. Copie o script em um arquivo vazio, salve-o como connect_screen.py
  2. Na seção head, defina o comando para executar na conexão (eu configurei "gedit" como exemplo, lembre-se das aspas). Também é possível definir um comando na desconexão, da mesma forma. Senão, deixe disconnect_command = "" como está.

    Se você usar um comando de desconexão, também descomente a linha:

    run_command(disconnect_command)
    

    e comente a linha:

    pass
    

    Como indicado no script

  3. Teste o script a partir de um terminal, conecte sua tela e veja se tudo funciona bem.
  4. Se tudo funcionar bem, adicione-o aos seus aplicativos de inicialização: Dash > Aplicativos de inicialização > Adicione o comando:

    /bin/bash -c "sleep 15&&python3 /path/to/connect_screen.py"
    

    O sleep 15 é fazer com que o desktop seja iniciado completamente antes que o script comece a ser executado. Apenas para ter certeza.

EDITAR

Como executar o script no início de uma maneira "inteligente".

O intervalo de sleep 15 deve funcionar em geral, mas como o tempo de inicialização difere por sistema, pode ser necessário fazer algumas experiências para encontrar o intervalo certo. Com uma pequena adição, o script se torna "inteligente" e espera que o comando xrandr seja bem-sucedido antes de iniciar o script real. Se você usar a versão abaixo, você só precisa adicionar o comando:

python3 /path/to/connect_screen.py

para seus aplicativos de inicialização. O uso adicional é exatamente o mesmo da versão acima.

O script

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

#--- set both commands (connect / disconnect) below
connect_command = "gedit"
disconnect_command = ""
#---

while True:
    time.sleep(5)
    try:
        subprocess.Popen(["xrandr"])
    except:
        pass
    else:
        break


# function to get the output of xrandr
def get(cmd): return subprocess.check_output(cmd).decode("utf-8")
# - to count the occurrenc of " connected "
def count_screens(xr): return xr.count(" connected ")
# - to run the connect / disconnect command(s)
def run_command(cmd): subprocess.Popen(["/bin/bash", "-c", cmd])

# first count
xr1 = None

while True:
    time.sleep(5)
    # second count
    xr2 = count_screens(get(["xrandr"]))
    # check if there is a change in the screen state
    if xr2 != xr1:
        if xr2 == 2:
            # command to run if connected (two screens)
            run_command(connect_command)
        elif xr2 == 1:
            # command to run if disconnected (one screen)
            # uncomment run_command(disconnect_command) to enable, then also comment out pass
            pass
            # run_command(disconnect_command)
    # set the second count as initial state for the next loop
    xr1 = xr2
    
por Jacob Vlijm 30.05.2015 / 20:11