Я пытаюсь запустить скрипт, расположенный в 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
Альтернативным решением было бы выполнение крошечного фонового скрипта. Запустив скрипт в фоновом режиме, я не смог измерить увеличение загрузки процессора.
Это простой и удобный способ запуска скрипта или любой другой команды при подключении или отключении второго экрана.
xrandr
появляется строка "connected" (запомните пробел после "connected", чтобы не допустить ложных совпадений с "disconnected"). Каждое событие представляет собой подключенный экран.#!/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
connect_screen.py
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
Как указано в скрипте
Если все работает нормально, добавьте его в приложения для запуска: Dash > Запуск приложений > Добавить команду:
/bin/bash -c "sleep 15&&python3 /path/to/connect_screen.py".
Спящий 15 должен полностью запустить рабочий стол до того, как начнется выполнение сценария. Просто чтобы убедиться.
Перерыв сна 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
Этого также можно добиться с помощью следующего сценария 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