Как я могу обнаружить, когда монитор включается или отключается?

Эмпирическое правило, по крайней мере, в Debian-приправленных системах:

  • /usr/local для материала, который "в масштабе всей системы" — т.е. /usr/local имеет тенденцию быть в значении по умолчанию дистрибутива $PATH, и следует за стандартной иерархией каталогов UNIX с /usr/local/bin, /usr/local/lib, и т.д.

  • /opt для материала Вы не доверяете для создания в масштабе всей системы с префиксами на приложение — т.е. /opt/firefox-3.6.8, /opt/mono-2.6.7, и так далее. Материал в здесь требует более осторожного управления, но, также менее вероятно, повредит Вашу систему — и легче удалить, так как Вы просто удаляете папку, и это пошло.

54
01.09.2017, 18:46
7 ответов

Примечание: Это было протестировано на ноутбуке с i915 управляемая видеокарта.


Фон

Примечание: Когда новый экран включается, никакое событие не отправляется в хост, это осталось верным даже после моего последнего редактирования. Таким образом, единственный путь состоит в том, чтобы использовать опрос. Попытка сделать их максимально эффективными...

РЕДАКТИРОВАНИЕ № 3

Наконец существует одно лучшее решение (через ACPI):

Нет все еще никакого события, но ACPI кажется более эффективным, чем xrandr запросить. (Nota: Это требует загруженных модулей ядра ACPI, но не требует полномочий пользователя root).

Мое конечное решение (использующий удар):

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.

Некоторые документы

14
27.01.2020, 19:33

Графически Вы видите, распознан ли монитор с Monitor, Я знаю, что можно найти это на Ubuntu, Fedora и других в этом (или подобное) местоположение.

Система/Предпочтения/Монитор

И Вы можете turn-on/off любой монитор, Вы хотите или используете обоих в то же время с дублирующимся изображением в обоих мониторах или независимых мониторах

-6
27.01.2020, 19:33

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

В следующем файле существует маленькая демонстрация C. http://www.kernel.org/doc/pending/hotplug.txt

0
27.01.2020, 19:33

Главным образом система/прикладное программное обеспечение на Linux сегодня использовала некоторые методы IPC для того, чтобы общаться друг с другом. D-шина теперь главным образом используется с приложениями GNOME и могла бы помочь.

Журнал Linux:

D-ШИНА может упростить передающие события или сигналы, через систему, позволив различные компоненты в системе связаться и в конечном счете интегрироваться лучше. Например, Bluetooth dæmon может отправить, входящий вызов сигнализируют, что Ваш аудиоплеер может прервать, отключив звук объема, пока вызов не заканчивается.

вики:

D-шина предоставляет обоих системный демон (для событий, таких как "новое устройство добавленная" или "очередь печати, измененная") и per-user-login-session демон (для общих потребностей межпроцессного взаимодействия среди пользовательских приложений)

Существует даже библиотека Python для этого, и человечность недавно использовала эту способность, которая назвала "дух времени".

0
27.01.2020, 19:33
[119165] Следующие строки появились в [119447]удевадмовском мониторе

kill -s SIGHUP [pid]

при подключении монитора к VGA-коннектору. Так что, возможно, есть способ разобраться в этом. [119168]

4
27.01.2020, 19:33

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

#!/bin/bash

SCREEN_LEFT=DP2
SCREEN_RIGHT=eDP1
START_DELAY=5

renice +19 $$ >/dev/null

sleep $START_DELAY

OLD_DUAL="dummy"

while [ 1 ]; do
    DUAL=$(cat /sys/class/drm/card0-DP-2/status)

    if [ "$OLD_DUAL" != "$DUAL" ]; then
        if [ "$DUAL" == "connected" ]; then
            echo 'Dual monitor setup'
            xrandr --output $SCREEN_LEFT --auto --rotate normal --pos 0x0 --output $SCREEN_RIGHT --auto --rotate normal --below $SCREEN_LEFT
        else
            echo 'Single monitor setup'
            xrandr --auto
        fi

        OLD_DUAL="$DUAL"
    fi

    inotifywait -q -e close /sys/class/drm/card0-DP-2/status >/dev/null
done

Лучше всего вызывать его из вашего .xsessionrc, не забывая окончание &. Опрос с помощью xrandr вызвал серьезные проблемы с удобством использования на моем новом ноутбуке (мышь периодически зависала).

3
27.01.2020, 19:33

Я написал очень хороший скрипт, используя bash, gawk, xrandr и xev. Это довольно чисто в том смысле, что оно не возится с какими-либо системными устройствами и не требует обширных знаний о таких устройствах, вместо этого полагается исключительно на использование xevи randrдля обнаружения подключенных мониторов. Сценарий awk предназначен только для разбора и выбора правильных событий.

Note: Requires xev v1.2.4 or higher

Рекомендуется для пользователей ноутбуков, которые постоянно взаимодействуют с другими внешними мониторами.

#!/bin/bash

function monitor_xevents {
    local connected_monitors=()
    local monitor

    for monitor in $(xrandr --listactivemonitors | awk '/^\s+[0-9]+:/ {print $4}'); do
        connected_monitors+=("$monitor")
    done

    xev -root -event randr -1 | stdbuf --output=L gawk --sandbox \
        --source "BEGIN{$(printf -- 'monitors["%s"]=1\n' ${connected_monitors[@]})}" \
        --source 'BEGIN {
            pat=@/output (.[^,]*),.*connection RR_(\w+),/
            for (monitor in monitors)
                print monitor, "connected"
        }
        !/crtc None/ && match ($0, pat, s) {
            # Newly discovered monitor at runtime
            if (!(s[1] in monitors)) {
                monitors[s[1]] = 1
                print s[1], "connected"
                next
            }
            switch (s[2]) {
                case "Connected":
                    if (!monitors[s[1]])
                        monitors[s[1]] = 1
                    else next
                    break
                case "Disconnected":
                    if (monitors[s[1]])
                        monitors[s[1]] = 0
                    else next
                    break
            }
            print s[1], tolower(s[2])
        }'
}

while read output status; do
    printf "$output was $status\n"
done < <(monitor_xevents)

Вы можете запустить его как службу systemd пользователя :

[Unit]
Description="Monitor hotplug notifier"

[Service]
ExecStart='/home/chigozirim/Dev/mon.sh'
Restart=on-failure
RestartSec=5s
RemainAfterExit=yes

[Install]
WantedBy=default.target

При запуске он сначала сообщает вам обо всех подключенных мониторах, а затем, когда вы продолжаете использовать его, он сообщает вам, когда монитор подключен или отключен.

Пример вывода:

Jan 06 01:48:18 ArcoB mon.sh[495478]: eDP-1 was connected
Jan 06 01:48:18 ArcoB mon.sh[495478]: HDMI-1-0 was connected
Jan 06 18:51:13 ArcoB mon.sh[495478]: HDMI-1-0 was disconnected
Jan 06 20:29:19 ArcoB mon.sh[495478]: HDMI-1-0 was connected
Jan 07 12:47:23 ArcoB mon.sh[495478]: HDMI-1-0 was disconnected
...

Поскольку я пользуюсь ноутбуком,eDP-1(Embedded Display Port 1 )в основном является моим ноутбуком, поэтому он никогда не отключается.

Вы можете расширить его, чтобы вызывать другие скрипты и т. д. Это был просто POC для тех, кто не хочет начинать писать C/C++ эквивалент вышеописанного.

2
07.01.2021, 18:01

Теги

Похожие вопросы