web-dev-qa-db-fra.com

Exécuter le script lorsque le moniteur est connecté

J'essaie d'exécuter un script situé dans usr/local/bin/ lorsque je connecte un moniteur externe à mon ordinateur portable. J'ai essayé d'ajouter une nouvelle règle udevmais cela n'a pas fonctionné. J'ai créé un nouveau fichier dans /etc/udev/rules.d appelé vga-monitor-connect.rules. Le contenu du fichier était

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

J'ai pris la ligne de cette réponse

Après avoir cherché en ligne, j'ai aussi essayé la règle suivante

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

Cependant cela n'a pas fonctionné non plus.

J'ai exécuté le script manuellement et je peux confirmer que cela fonctionne pour que ce ne soit pas un problème avec mon script.

Je tiens également à préciser que je ne connais pas grand chose à udevet que la règle que j'ai utilisée est peut-être fausse. Si quelqu'un connaît la règle appropriée à mon problème, veuillez laisser une réponse.

Ma carte graphique est un chipset intégré Intel GM965

12
Rumesh

Une autre façon d'exécuter une commande si un écran est connecté ou déconnecté

Une solution alternative consisterait à exécuter un script d'arrière-plan minuscule. En exécutant le script ci-dessous en arrière-plan, je ne pouvais mesurer aucune augmentation de la charge du processeur.

C'est un moyen simple et pratique d'exécuter un script ou toute autre commande lorsqu'un deuxième écran est connecté ou déconnecté.

Le script d'exemple

  • Vérifie simplement toutes les cinq secondes combien de fois la chaîne "connectée" apparaît dans la sortie de la commande xrandr(gardez l'espace après "connected" pour éviter les correspondances fausses avec "disconnected"). Chaque occurrence représente un écran connecté.
  • Si le nombre d'occurrences change, un écran est connecté ou déconnecté. La modification est "remarquée" par le script et peut être connectée à une commande que vous pouvez définir dans la section head du script.

Le scénario

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

Comment utiliser

  1. Copiez le script dans un fichier vide, enregistrez-le sous connect_screen.py
  2. Dans la section head, configurez la commande pour qu'elle soit exécutée sur connect (par exemple, "gedit", attention aux guillemets). En outre, il est également possible de définir une commande sur Disconnect. Sinon, laissez disconnect_command = "" tel quel.

    Si vous utilisez une commande de déconnexion, décommentez également la ligne:

    run_command(disconnect_command)
    

    et commentez la ligne:

    pass
    

    Comme indiqué dans le script

  3. Testez le script depuis un terminal, connectez votre écran et voyez si tout fonctionne bien.
  4. Si tout fonctionne correctement, ajoutez-le à vos applications de démarrage: Dash> Applications de démarrage> Ajoutez la commande:

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

    Le sleep 15 permet de faire démarrer complètement le bureau avant que le script ne commence à s'exécuter. Juste pour en être certain.


MODIFIER

Comment exécuter le script au démarrage de manière "intelligente".

La pause de sleep 15 devrait fonctionner en général, mais comme le temps de démarrage diffère d’un système à l’autre, il peut être nécessaire d’expérimenter pour trouver le bon temps de pause. Avec un petit ajout, le script devient "intelligent" et attend que la commande xrandrsoit réussie avant de démarrer le script. Si vous utilisez la version ci-dessous, il vous suffit d'ajouter la commande:

python3 /path/to/connect_screen.py

à vos applications de démarrage. L'utilisation ultérieure est identique à la version ci-dessus.

Le scénario

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

Ceci peut être réalisé à partir du script bash suivant.

#!/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
2
Bhaskar K C