Як я можу виявити, коли монітор підключений чи відключений від мережі?


53

Чи є якась подія, яка викликається, коли я підключаю або виймаю зовнішній монітор у DisplayPort свого ноутбука? ACPID і UDEV взагалі не реагують.

Я використовую вбудовану графіку на інте-чіпі. Ось подібна дискусія, яка вже пару років.

Я не хочу використовувати опитування, але мені потрібно мати певну конфігурацію, яка встановлює налаштування дисплея автоматично залежно від того, підключений дисплей.


4
Це можна зробити за допомогою udev. Яка версія вашого ядра? Використовуєте ви KMS (налаштування режиму ядра)?
Енді,

Дякую за відповідь. Я не впевнений у KMS, але, як я вже говорив у запитанні, udev не надсилає жодних подій. ( udevadm monitor - власність взагалі не реагує)
janoliver

@Andy: востаннє, коли це з’явилося , здавалося, що для більшості систем потрібне опитування. Якщо ви знайшли спосіб викликати подію udev, можете відповісти на це запитання?
Жил 'SO- перестань бути злим'

1
Нарешті я запустив його завантаження i915 як модуль ядра.
янолівер

3
Ви можете використовувати xrandr або дисперс, щоб виявити, чи був підключений зовнішній монітор. Github.com/wertarbyte/autorandr може показати вам, як ними користуватися. Але xrandr / disper може не підтримувати вашу відеокарту.
номер5

Відповіді:


13

ПРИМІТКА. Це було перевірено на ноутбуці з графічною картою, керованою 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 .

Деякі документи


4

Наступні рядки з'явилися в udevadm monitor

KERNEL[46578.184280] change   /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
UDEV  [46578.195887] change   /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)

при підключенні монітора до VGA-роз'єму. Тож може бути спосіб розібратися в цьому.


З nVidia 9800 GT та власними драйверами монітор udevadm нічого не показує, коли я підключаю монітор HDMI. Яке обладнання / драйвери ви використовуєте?
Франкстер

Шкода, що це не працює для мене надійно. Іноді я отримую ці повідомлення про події, коли я підключаю монітор, а іноді - ні.
Тобіас

3

Для тих, хто з будь-якої причини не хоче скористатися маршрутом гарячої підключення, все одно можливо не опитуватися в сценарії за допомогою inotifywait:

#! / бін / баш

SCREEN_LEFT = DP2
SCREEN_RIGHT = eDP1
START_DELAY = 5

renice +19 $$> / dev / null

сон $ START_DELAY

OLD_DUAL = "манекен"

поки [1]; робити
    DUAL = $ (cat / sys / class / drm / card0-DP-2 / status)

    if ["$ OLD_DUAL"! = "$ DUAL"]; тоді
        if ["$ DUAL" == "підключено"]; тоді
            echo "Налаштування подвійного монітора"
            xrandr - вихід $ SCREEN_LEFT --auto - повернути нормально --pos 0x0 --output $ SCREEN_RIGHT --auto - повернути нормально - нижче $ SCREEN_LEFT
        ще
            echo "Один параметр монітора"
            xrandr --auto
        фі

        OLD_DUAL = "$ DUAL"
    фі

    inotifywait -q -e закрити / sys / class / drm / card0-DP-2 / status> / dev / null
зроблено

Найкраще викликати ваш .xsessionrc, не забуваючи про закінчення &. Опитування з xrandr спричинило серйозні проблеми в користуванні на моєму абсолютно новому ноутбуці (миша періодично буде зупинятися).


Я б не подумав, що ви можете використовувати inotify /procі просто робити inotifywait -q -e close /sys/class/drm/card0-DP-2/status це не закінчилося після відключення DP-2 у моїй системі
nhed

3

Я дотримувався використання srandrd . Він контролює X події та запускає ваш сценарій, коли дисплей підключається чи відключається.


0

Очевидно, має бути щось! Файлова система :) / sys повідомляє простір користувачів, яке обладнання доступне, тому інструменти простору користувачів (такі як udev або mdev) можуть динамічно заповнювати каталог "/ dev" вузлами пристроїв, що представляють наявне на даний момент обладнання. Linux надає два інтерфейси гарячої підключення: / sbin / hotplug та netlink.

У наступному файлі є невелика демонстрація C. http://www.kernel.org/doc/pending/hotplug.txt


0

В основному системне / прикладне програмне забезпечення в Linux сьогодні використовує деякі методи ipc для спілкування один з одним. D-Bus зараз використовується в основному для додатків GNOME, і може допомогти.

Журнал Linux:

D-BUS може сприяти надсиланню подій або сигналів через систему, дозволяючи різним компонентам системи спілкуватися і в кінцевому рахунку краще інтегруватися. Наприклад, Bluetooth dæmon може надіслати сигнал вхідного дзвінка, який ваш музичний плеєр може перехопити, приглушуючи гучність до завершення дзвінка.

Вікі:

D-Bus постачає як системний демон (для таких подій, як "додано новий апаратний пристрій" чи "чергу принтера змінено"), так і демон-сеанс для входу за користувачем (для загальних потреб міжкомунікаційних комунікацій серед програм користувача)

Для цього є навіть бібліотека Python, і нещодавно ubuntu використовував цю здатність, яку називали " zeitgeist ".


-6

Графічно ви можете побачити, чи монітор розпізнається Monitor, я знаю, що ви можете знайти це в Ubuntu, Fedora та інших у цьому (або подібному) місці.

Система / Налаштування / Монітор

І ви можете вмикати / вимикати будь-який потрібний монітор або використовувати обидва одночасно з подвійним зображенням на обох моніторах або незалежних моніторах


2
Він попросив подію, яка спрацьовує, коли монітор підключається / відключається від мережі
Michael Mrozek

Ви тут заглядали? stackoverflow.com/questions/5469828/…
Satish
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.