Führen Sie das Skript aus, wenn der Monitor angeschlossen ist

12

Ich versuche, ein Skript auszuführen, in usr/local/bin/dem ich einen externen Monitor an meinen Laptop anschließe. Ich habe versucht, eine neue udevRegel hinzuzufügen, aber das hat nicht funktioniert. Ich habe eine neue Datei in /etc/udev/rules.daufgerufen vga-monitor-connect.rules. Der Inhalt der Datei war

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

Ich habe die Zeile aus dieser Antwort genommen

Nach der Online-Suche habe ich auch die folgende Regel ausprobiert

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

Das hat aber auch nicht geklappt.

Ich habe das Skript manuell ausgeführt und kann bestätigen, dass es funktioniert, sodass es mit meinem Skript kein Problem darstellt.

Ich möchte auch klarstellen, dass ich nicht viel darüber weiß, udevsodass die Regel, die ich verwendet habe, möglicherweise falsch ist. Wenn jemand die richtige Regel für mein Problem kennt, hinterlassen Sie bitte eine Antwort.

Meine Grafikkarte ist ein Intel GM965 integrierter Chipsatz

Rumesh
quelle
Möchtest du das konkret so machen? Ein winziges Hintergrundskript wäre ein Kinderspiel.
Jacob Vlijm
@JacobVlijm Wie wäre das Drehbuch? Können Sie ein Beispiel zeigen?
Rumesh
Ist es nur auszulösen, wenn (ein) zweiter Monitor angeschlossen ist?
Jacob Vlijm
Ja, ich muss mein eigenes Skript ausführen, wenn ich den zweiten Monitor
anhänge
1
Kein Problem, nehmen Sie sich Zeit und antworten Sie, wenn Sie können :)
Rumesh

Antworten:

7

Eine alternative Möglichkeit, einen Befehl auszuführen, wenn ein Bildschirm verbunden oder getrennt ist

Eine alternative Lösung wäre, ein winziges Hintergrundskript auszuführen. Wenn ich das folgende Skript im Hintergrund laufen lasse, konnte ich keinen Anstieg der Prozessorauslastung messen.

Es ist eine einfache und bequeme Möglichkeit, ein Skript oder einen anderen Befehl auszuführen, wenn ein zweiter Bildschirm verbunden oder getrennt wird.

Das Beispielskript

  • Überprüft einfach alle fünf Sekunden, wie oft die Zeichenfolge "connected" in der Ausgabe des Befehls vorkommt xrandr(beachtet das Leerzeichen nach "connected", um falsche Übereinstimmungen mit "disconnected" zu vermeiden). Jedes Vorkommen repräsentiert einen verbundenen Bildschirm.
  • Wenn sich die Anzahl der Vorkommen ändert, wurde entweder ein Bildschirm verbunden oder getrennt. Die Änderung wird vom Skript "bemerkt" und kann mit einem Befehl verbunden werden, den Sie im Kopfteil des Skripts einstellen können.

Das Drehbuch

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

Wie benutzt man

  1. Kopieren Sie das Skript in eine leere Datei und speichern Sie es unter connect_screen.py
  2. Stellen Sie im head-Bereich den Befehl so ein, dass er bei connect ausgeführt wird (ich setze als Beispiel "gedit", beachte die Anführungszeichen). Ebenso ist es möglich, einen Befehl beim Trennen zu setzen. Sonst lass disconnect_command = ""wie es ist.

    Wenn Sie einen Disconnect-Befehl verwenden, kommentieren Sie auch die Zeile aus:

    run_command(disconnect_command)

    und die Zeile auskommentieren:

    pass

    Wie im Skript angegeben

  3. Führen Sie das Skript auf einem Terminal aus, schließen Sie Ihren Bildschirm an und prüfen Sie, ob alles funktioniert.
  4. Wenn alles in Ordnung ist, fügen Sie es Ihren Startanwendungen hinzu: Dash> Startanwendungen> Fügen Sie den Befehl hinzu:

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

    Das sleep 15ist auf den Desktop machen startet vollständig , bevor das Skript zu laufen beginnt. Nur um sicher zugehen.


BEARBEITEN

So führen Sie das Skript beim Start "intelligent" aus.

Die Unterbrechung von sleep 15sollte im Allgemeinen funktionieren, aber da die Startzeit je nach System unterschiedlich ist, kann es einige Experimente erfordern, um die richtige Unterbrechungszeit zu finden. Mit einem kleinen Zusatz wird das Skript "intelligent" und wartet, bis der xrandrBefehl erfolgreich ist, bevor das eigentliche Skript gestartet wird. Wenn Sie die folgende Version verwenden, müssen Sie nur den Befehl hinzufügen:

python3 /path/to/connect_screen.py

zu Ihren Startup-Anwendungen. Die weitere Verwendung entspricht genau der obigen Version.

Das Drehbuch

#!/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
Jacob Vlijm
quelle
4
Sie geben einem Mann mit einem kaputten schnellen Auto ein Fahrrad, anstatt das Auto zu
reparieren
1
@solsTiCe 1. Dies ist kein Fahrrad, sondern eine perfekt funktionierende Option. Denken Sie daran, dass alle Benachrichtigungs-, Ereignis- oder was auch immer angesteuerten Aktionen darin bestehen, irgendwie eine Schleife auszuführen. 2. Ich schlage vor, dass Sie den Ferrari dann reparieren.
Jacob Vlijm,
1
@Rumesh Skripte in läuft $PATH mit Dateierweiterung und mit Sprache vorhergehenden ist eine nicht-so-elegante Lösung. Die Frage ist, ob Sie es für einen Benutzer oder für alle Benutzer ausführen möchten. Im letzten Fall wird ein anderes Setup als das vorgeschlagene benötigt, aber vorzugsweise nicht das, das Sie vorschlagen :). Das sleep 15könnte nicht ausreichen, aber eine elegantere Lösung könnte sein, die Unterbrechung "schlau" zu machen, das Skript versuchen zu lassen / es sei denn, es wird gestartet, bis die Startprozedur "bereit" ist, damit das Skript ausgeführt werden kann. Wäre eine kleine Ergänzung. Gib mir Bescheid.
Jacob Vlijm,
1
@Rumesh Skripte in $PATHnicht Spracherweiterung haben sollte und ausführbar sein, also ohne laufen python3siehe lintian.debian.org/tags/script-with-language-extension.html
Jacob Vlijm
1
@JacobVlijm Ich hatte es bereits so eingestellt, dass es ausführbar ist, also kann ich es wohl einfach benutzenconnect_screen
Rumesh
2

Dies kann auch mit dem folgenden Bash-Skript erreicht werden.

#!/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
Bhaskar KC
quelle