ПРИМІТКА. Це було перевірено на ноутбуці з графічною картою, керованою 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 секунд.
Поки це працює, підключіть і / або відключіть екран / монітор і подивіться, що відбувається. Таким чином, ви можете створити невелику тестову функцію Баша:
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
.
Деякі документи