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


13

Я пытаюсь запустить сценарий, расположенный usr/local/bin/при подключении внешнего монитора к ноутбуку. Я пытался добавить новое udevправило, но это не сработало. Я создал новый файл в /etc/udev/rules.dAndroid 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


Вы специально хотите сделать это так? Крошечный фоновый скрипт был бы куском пирога.
— Якоб Влийм

@JacobVlijm Каким будет сценарий? Не могли бы вы показать пример.
— Румеш

Это только для запуска, если (любой) второй монитор подключен?
— Джейкоб Влейм

Да, мне нужно запустить собственный скрипт, когда я присоединяю второй монитор
— Rumesh

1
Нет проблем, не торопитесь и ответьте, когда сможете :)
— Румеш

Ответы:


7

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

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

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

Пример сценария

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

Сценарий

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

Как пользоваться

  1. Скопируйте скрипт в пустой файл, сохраните его как connect_screen.py
  2. В разделе заголовка установите команду для запуска по соединению (в качестве примера я привел «gedit», обратите внимание на кавычки). Также можно установить команду на отключение, аналогично. Остальное оставь disconnect_command = ""как есть.

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

    run_command(disconnect_command)

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

    pass

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

  3. Протестируйте скрипт из терминала, подключите экран и посмотрите, все ли работает нормально.
  4. Если все работает нормально, добавьте его в автозагрузку приложений: Dash> Startup Applications> Add the command:

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

    sleep 15, Чтобы сделать рабочий стол запустить полностью до того , как скрипт начинает работать. Просто чтобы убедиться.


РЕДАКТИРОВАТЬ

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

Прерывание sleep 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

4
Вы даете велосипед человеку с сломанной быстрой машиной вместо того, чтобы
— починить

1
@solsTiCe 1. Это не велосипед, а совершенно функциональный вариант. Имейте в виду, что все уведомления, события или другие управляемые действия существуют для запуска какого-то цикла. 2. Тогда я предлагаю вам починить Ferrari.
— Джейкоб Влейм

1
@Rumesh запускает сценарии $PATH с расширением файла и с предыдущим языком - не слишком элегантное решение. Вопрос в том, хотите ли вы запустить его для одного пользователя или для всех пользователей. В последнем случае нужна другая настройка, чем предложенная, но желательно не та, которую вы предлагаете :). sleep 15Не может быть достаточно, но более элегантное решение могло бы сделать перерыв «умный», пусть попробовать скрипт / за исключением того, чтобы запустить до тех пор , пока процедура запуска «готова» для сценария для запуска. Было бы незначительным дополнением. Дай мне знать.
— Джейкоб Влейм

1
Скрипты @Rumesh в $PATHне должны иметь языкового расширения и быть исполняемыми, поэтому запускайте без python3просмотра lintian.debian.org/tags/script-with-language-extension.html
— Джейкоб Влийм

1
@JacobVlijm Я уже установил, что он должен быть исполняемым ранее, поэтому я думаю, что я могу просто использоватьconnect_screen
— Rumesh

2

Это может быть достигнуто с помощью следующего скрипта 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.