Запустити сценарій, коли підключений монітор


13

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

Чи потрібно лише спрацьовувати, якщо (будь-який) другий монітор підключений?
Яків Влійм

Так, мені потрібно запустити власний сценарій, коли я приєдную другий монітор
Румеш

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 = ""як є.

    Якщо ви використовуєте команду disconnect-, також коментуйте рядок:

    run_command(disconnect_command)

    і прокоментуйте рядок:

    pass

    Як зазначено в сценарії

  3. Тестуйте запуск сценарію з терміналу, підключіть екран і побачите, чи все працює добре.
  4. Якщо все працює нормально, додайте його до своїх програм запуску: Dash> Applications for Startup> Add the command:

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

    sleep 15, Щоб зробити робочий стіл запустити повністю до того , як скрипт починає працювати. Просто для переконання.


EDIT

Як запустити сценарій при запуску «розумним» способом.

Перерва 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може бути недостатньо, але більш елегантним рішенням може бути зробити перерву "розумною", нехай сценарій спробує / крім запуску, поки процедура запуску не буде "готова" для запуску сценарію. WO було б незначним доповненням. Дай мені знати.
Яків Влійм

1
Сценарії @Rumesh у $PATHне повинні мати розширення мови та бути виконуваними, тому запустіть без python3див. Lintian.debian.org/tags/script-with-language-extension.html
Якоб Влійм

1
@JacobVlijm Я вже встановив його виконуваним раніше, тому, мабуть, я можу просто використовуватиconnect_screen
Румеш,

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.