Esegui script quando il monitor è collegato


12

Sto cercando di eseguire uno script situato usr/local/bin/quando collego un monitor esterno al mio laptop. Ho provato ad aggiungere una nuova udevregola ma non ha funzionato. Ho creato un nuovo file in /etc/udev/rules.dchiamato vga-monitor-connect.rules. I contenuti del file erano

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

Ho preso la linea da questa risposta

Dopo aver cercato online ho anche provato la seguente regola

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

Tuttavia, neanche questo ha funzionato.

Ho eseguito lo script manualmente e posso confermare che funziona in modo che non sia un problema con il mio script.

Voglio anche chiarire che non ne so molto, udevquindi la regola che ho usato potrebbe essere sbagliata. Se qualcuno conosce la regola corretta per il mio problema, ti preghiamo di lasciare una risposta.

La mia scheda grafica è un chipset integrato Intel GM965


Vuoi specificatamente farlo in questo modo? Una minuscola sceneggiatura di sfondo sarebbe un gioco da ragazzi.
Jacob Vlijm,

@JacobVlijm Come sarebbe lo script? Potresti mostrare un esempio.
Rumesh,

È solo possibile attivare se (qualsiasi) secondo monitor è collegato?
Jacob Vlijm,

Sì, devo eseguire il mio script quando
allego

1
Nessun problema, prenditi il ​​tuo tempo e rispondi quando puoi :)
Rumesh,

Risposte:


7

Un modo alternativo per eseguire un comando se uno schermo è collegato o disconnesso

Una soluzione alternativa sarebbe quella di eseguire un piccolo script in background. Eseguendo lo script di seguito in background, non sono riuscito a misurare alcun aumento del carico del processore.

È un modo semplice e conveniente per eseguire uno script o qualsiasi altro comando, quando una seconda schermata è connessa o disconnessa.

Lo script di esempio

  • Controlla semplicemente ogni cinque secondi quante volte si verifica la stringa "connesso" nell'output del comando xrandr(attenzione allo spazio dopo "connesso" per evitare false corrispondenze con "disconnesso"). Ogni occorrenza rappresenta una schermata collegata.
  • Se il numero di occorrenze cambia, uno schermo è stato collegato o disconnesso. La modifica viene "notata" dallo script e può essere collegata a un comando, è possibile impostare nella sezione head dello script.

Il copione

#!/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

Come usare

  1. Copia lo script in un file vuoto, salvalo come connect_screen.py
  2. Nella sezione head, imposta il comando per eseguire su connect (ho impostato "gedit" come esempio, attenzione alle virgolette). Allo stesso modo è anche possibile impostare un comando su disconnect. Altrimenti partire disconnect_command = ""così com'è.

    Se si utilizza un comando di disconnessione, rimuovere anche il commento dalla riga:

    run_command(disconnect_command)

    e commenta la riga:

    pass

    Come indicato nella sceneggiatura

  3. Esegui il test dello script da un terminale, collega lo schermo e verifica se tutto funziona correttamente.
  4. Se tutto funziona correttamente, aggiungilo alle applicazioni di avvio: Dash> Applicazioni di avvio> Aggiungi il comando:

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

    Il sleep 15è quello di rendere il desktop avvio completamente prima che lo script inizia a correre. Giusto per essere sicuri.


MODIFICARE

Come eseguire lo script all'avvio in modo "intelligente".

L'interruzione sleep 15dovrebbe funzionare in generale, ma poiché il tempo di avvio varia a seconda del sistema, potrebbero essere necessari alcuni esperimenti per trovare il momento giusto. Con una piccola aggiunta, lo script diventa "intelligente" e attende che il xrandrcomando abbia esito positivo prima di avviare lo script effettivo. Se usi la versione seguente, devi solo aggiungere il comando:

python3 /path/to/connect_screen.py

alle tue applicazioni di avvio. L'ulteriore utilizzo è esattamente lo stesso della versione precedente.

Il copione

#!/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

4
Stai dando una bicicletta a un uomo con un'auto veloce rotta invece di riparare l'auto ...
solsTiCe

1
@solsTiCe 1. Questa non è una bicicletta, ma un'opzione perfettamente funzionale. Tieni presente che tutte le azioni guidate da notifica, evento o qualunque altra cosa esistano eseguendo in qualche modo un qualche tipo di ciclo. 2. Ti suggerisco di riparare la Ferrari allora.
Jacob Vlijm,

1
@Rumesh che esegue script $PATH con estensione di file e con la lingua precedente è una soluzione non così elegante. La domanda è se si desidera eseguirlo per un utente o per tutti gli utenti. Nell'ultimo caso, è necessaria una configurazione diversa da quella suggerita, ma preferibilmente non quella che stai suggerendo :). Il sleep 15potrebbe non essere sufficiente, ma una soluzione più elegante potrebbe essere quello di fare la pausa "intelligente", lasciare che il tentativo script / tranne per iniziare fino a quando la procedura di avvio è "pronto" per l'esecuzione di script. Potrebbe essere un'aggiunta minore. Fammi sapere.
Jacob Vlijm,

1
Gli script di @Rumesh in $PATHnon dovrebbero avere l'estensione della lingua ed essere eseguibili, quindi esegui senza python3vedere lintian.debian.org/tags/script-with-language-extension.html
Jacob Vlijm

1
@JacobVlijm L'avevo già impostato come eseguibile prima, quindi credo di poterlo usareconnect_screen
Rumesh

2

Ciò può essere ottenuto anche seguendo il seguente script bash.

#!/usr/bin/env bash

xrandr=$(xrandr)

con_monitors=$(echo $xrandr | grep -c " connected ")

    if [[ $con_monitors -gt 1 ]]; then
        # All the layouts are saved in "screenlayout" folder.
        # eg cmd. xrandr --output HDMI-1 --mode 2560x1440 --pos 0x0 --rotate normal --output DP-1 --off --output eDP-1 --primary --mode 1920x1080 --pos 283x1440 --rotate normal --output DP-2 --off
        for layout in ~/.screenlayout/*.sh; do
            ./layout
        done
    fi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.