ПРИМЕЧАНИЕ. Тестирование проводилось на ноутбуке с графической картой с управлением i915.
Фон
ПРИМЕЧАНИЕ. Когда подключен новый экран, на хост не отправляется событие, оно остается верным даже после моего последнего редактирования. Таким образом, единственный способ - использовать опрос. Пытаясь сделать их максимально эффективными ...
РЕДАКТИРОВАТЬ № 3
Наконец, есть одно лучшее решение (через ACPI):
Там еще нет события, но ACPI кажется более эффективным, чем xrandr
запросить. (Примечание: для этого требуются загруженные модули ядра ACPI, но не требуются права root).
Мое окончательное решение (с использованием bash):
isVgaConnected() {
local crtState
read -a < /proc/acpi/video/VID/CRT0/state crtState
test $(( ( ${crtState[1]} >>4 ) ${1:+*-1+1} )) -ne 0
}
Теперь тест:
$ if isVgaConnected; then echo yes; else echo no; fi
yes
Он подключен, так что теперь я отключаю его:
$ if isVgaConnected; then echo yes; else echo no; fi
no
Примечание: ${1:+*-1+1}
разрешить логическое рассуждение: Если что - то присутствует , ответ будет перевернутой: ( crtState >> 4 ) * -1 + 1
.
и последний сценарий:
#!/bin/bash
export crtProcEntry=/proc/acpi/video/VID/CRT0/state
isVgaConnected() {
local crtState
read -a < $crtProcEntry crtState
test $(( ( ${crtState[1]} >>4 ) ${1:+*-1+1} )) -ne 0
}
delay=.1
unset switch
isVgaConnected || switch=not
while :;do
while isVgaConnected $switch;do
sleep $delay
done
if [ "$switch" ];then
unset switch
echo VGA IS connected
# doing something while VGA is connected
else
switch=not
echo VGA is NOT connected.
# doing something else, maybe.
fi
done
ПРЕДУПРЕЖДЕНИЯ: легче xrandr
, но не менее важно, с задержкой менее 0,02 секунды, скрипт Bash перейдет на вершину процесса пожирателей ресурсов ( top
)!
Пока это стоит ~ 0,001 сек:
$ time read -a </proc/stat crtStat
Это требует ~ 0,030 сек:
$ read -a < /proc/acpi/video/VID/CRT0/state crtState
Это большое! Таким образом, в зависимости от того, что вам нужно, delay
может быть разумно установлено между 0.5
и 2
.
РЕДАКТИРОВАТЬ № 2
Я наконец-то нашел что-то, используя это:
Важный отказ от ответственности: игра с /proc
и /sys
записи может сломать вашу систему !!! Так что не пытайтесь сделать следующее на производственных системах.
mapfile watchFileList < <(
find /sys /proc -type f 2>/dev/null |
grep -i acpi\\\|i91
)
prompt=("/" "|" '\' '-');
l=0
while :; do
mapfile watchStat < <(
grep -H . ${watchFileList[@]} 2>/dev/null
)
for ((i=0;i<=${#watchStat[@]};i++)); do
[ "${watchStat[i]}" == "${oldStat[i]}" ] || echo ${watchStat[i]}
done
oldStat=("${watchStat[@]}")
sleep .5
printf "\r%s\r" ${prompt[l++]}
[ $l -eq 4 ]&&l=0
done
... после некоторой очистки от нежелательных записей:
for ((i=0;i<=${#watchFileList[@]};i++)); do
[[ "${watchFileList[$i]}" =~ /sys/firmware/acpi/interrupts/sci ]] &&
unset watchFileList[$i] && echo $i
done
Я был в состоянии прочитать это:
/proc/acpi/video/VID/CRT0/state:state: 0x1d
/proc/acpi/video/VID/CRT0/state:state: 0x0d
/proc/acpi/video/VID/CRT0/state:state: 0x1d
Когда я подключаю, отключаю и снова подключаю кабель монитора.
Оригинальный ответ
Когда запрашивается конфигурация (запущена system/preferences/monitor
или xrandr
), графические карты выполняют тип сканирования , поэтому при запуске xrandr -q
выдается информация, но вы должны опросить статус.
Я просмотрел все журналы (ядро, демон, X и т. Д.), Просматривая /proc
& /sys
, и, похоже, ничего не существует, чтобы удовлетворить ваш запрос.
Я тоже попробовал это:
export spc50="$(printf "%50s" "")"
watch -n1 '
find /proc/acpi/video -type f |
xargs grep -H . |
sed "s/^\([^:]*):/\1'$spc50'}:/;
s/^\(.\{50\}\) *:/\1 /"'
После всего этого, если вы запускаете, System/Preferences/Monitor
когда новый экран не был подключен или отключен, инструмент будет отображаться просто (обычно). Но если вы ранее подключали или отключали экран, иногда вы запускаете этот инструмент и увидите, что ваш рабочий стол выполняет сброс или обновление (то же самое, если вы запускаете xrandr
).
Похоже, это подтверждает, что этот инструмент запрашивает xrandr
(или работает аналогичным образом), периодически опрашивая состояние, начиная с момента его запуска.
Вы можете попробовать себя:
$ for ((i=10;i--;)); do xrandr -q | grep ' connected' | wc -l; sleep 1; done
1
1
1
2
2
2
1
1
1
1
Это покажет, сколько экранов (дисплеев) подключено, за 10 секунд.
Пока это работает, подключите и / или отключите ваш экран / монитор и посмотрите, что происходит. Таким образом, вы можете создать небольшую тестовую функцию Bash:
isVgaConnected() {
local xRandr=$(xrandr -q)
[ "$xRandr" == "${xRandr#*VGA1 con}" ] || return 0
return 1
}
который будет использоваться как в:
$ if isVgaConnected; then echo yes; fi
Но будьте осторожны, xrandr
занимает от 0,140 до 0,200 с, пока на вилках не происходит никаких изменений, и до 0,700 с, когда что-то было подключено или отключено непосредственно перед этим ( ПРИМЕЧАНИЕ. Похоже, что это не пожиратель ресурсов).
РЕДАКТИРОВАТЬ # 1
Чтобы убедиться, что я не преподаю что-то неправильное, я искал в Интернете и документах, но не нашел ничего о DBus и экранах .
Наконец, я запустил два разных окна dbus-monitor --system
(я тоже играл с опциями) и небольшой сценарий, который я написал:
$ for ((i=1000;i--;)); do isVgaConnected && echo yes || echo no; sleep .5; done
... и снова подключил, чем отключил монитор, много раз. Так что теперь я могу сказать:
- В этой конфигурации с использованием драйвера i915 нет другого способа, кроме
xrandr -q
как узнать, подключен ли монитор или нет.
Но будьте осторожны, потому что, похоже, других путей нет. Например, xrandr
кажется, что делится этой информацией, поэтому мой рабочий стол GNOME переключился бы xinerama
автоматически ... когда я запустилсяxrandr
.
Некоторые документы