Запустить скрипт, когда монитор подключен

Я пытаюсь запустить скрипт, расположенный в usr/local/bin/, когда я подключаю внешний монитор к своему ноутбуку. Я попытался добавить новое правило udev, но это не сработало. Я создал новый файл в /etc/udev/rules.d под названием vga-monitor-connect.rules. Содержимое файла было

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

Я взял строку из этого ответа

После поиска в Интернете я также попробовал следующее правило

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

Однако это тоже не сработало.

Я запустил скрипт вручную и могу подтвердить, что он работает, поэтому у меня нет проблем с моим скриптом.

Я также хочу прояснить, что я не знаю много о udev, поэтому правило, которое я использовал, может быть неправильным. Если кто-нибудь знает правильное правило для моей проблемы, пожалуйста, оставьте ответ.

Моя видеокарта представляет собой интегрированный чипсет Intel GM965

13
задан 13 April 2017 в 15:24

2 ответа

Альтернативным способом выполнения команды, если экран подключен или отключен

Альтернативным решением было бы выполнение крошечного фонового скрипта. Запустив скрипт в фоновом режиме, я не смог измерить увеличение загрузки процессора.

Это простой и удобный способ запуска скрипта или любой другой команды при подключении или отключении второго экрана.

Пример скрипта

  • Просто проверяет каждые пять секунд, сколько раз в выводе команды xrandr появляется строка "connected" (запомните пробел после "connected", чтобы не допустить ложных совпадений с "disconnected"). Каждое событие представляет собой подключенный экран.
  • Если количество событий меняется, то экран либо подключен, либо отключен. Изменение "замечено" скриптом и может быть подключено к команде, это можно установить в головной части скрипта.

The 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

How to use

  1. Copy the script into a empty file, save it as connect_screen.py
  2. In the head section, set the command to run on connect ( I set "gedit" as a example, mind the quotes). Также можно установить команду на разъединение. В противном случае оставьте disconnect_command = "" как есть.

    Если Вы используете команду disconnect-, также не комментируйте строку:

    run_command(disconnect_command)
    

    и прокомментируйте строку:

     pass
    

    Как указано в скрипте

  3. Тестировать запуск скрипта с терминала, подключите экран и посмотрите, все ли работает нормально.
  4. Если все работает нормально, добавьте его в приложения для запуска: Dash > Запуск приложений > Добавить команду:

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

    Спящий 15 должен полностью запустить рабочий стол до того, как начнется выполнение сценария. Просто чтобы убедиться.


EDIT

Как запустить скрипт при запуске "умным" способом.

Перерыв сна 15 должен работать в целом, но так как время запуска отличается в зависимости от системы, это может занять некоторые эксперименты, чтобы найти правильное время перерыва. С небольшим добавлением, скрипт становится "умным", и ждет команды xrandr, чтобы быть успешным, прежде чем он запустит реальный скрипт. Если вы используете нижеприведенную версию, вам нужно только добавить команду:

python3 /path/to/connect_screen.py

в ваши Приложения запуска. Дальнейшее использование точно такое же, как и предыдущая версия.

Скрипт

#!/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
8
ответ дан 13 April 2017 в 15:24

Этого также можно добиться с помощью следующего сценария 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
2
ответ дан 4 October 2019 в 14:13

Другие вопросы по тегам:

Похожие вопросы: