HINWEIS: Dies wurde auf einem Laptop mit einer i915-Grafikkarte getestet.
Hintergrund
HINWEIS: Wenn ein neuer Bildschirm angeschlossen wird, wird kein Ereignis an den Host gesendet. Dies ist auch nach meiner letzten Bearbeitung der Fall. Der einzige Weg ist das Polling. Wir versuchen, sie so effizient wie möglich zu gestalten ...
EDIT # 3
Endlich gibt es eine bessere Lösung (über ACPI):
Es gibt noch keine Veranstaltung, aber ACPI scheint effizienter zu sein, als sich xrandr
zu erkundigen. (Hinweis: Hierfür müssen ACPI-Kernelmodule geladen sein, es sind jedoch keine Root-Berechtigungen erforderlich.)
Meine endgültige Lösung (mit bash):
isVgaConnected() {
local crtState
read -a < /proc/acpi/video/VID/CRT0/state crtState
test $(( ( ${crtState[1]} >>4 ) ${1:+*-1+1} )) -ne 0
}
Nun ein Test:
$ if isVgaConnected; then echo yes; else echo no; fi
yes
Es ist eingesteckt, also ziehe ich es jetzt heraus:
$ if isVgaConnected; then echo yes; else echo no; fi
no
HINWEIS: ${1:+*-1+1}
eine Genehmigung boolean Argument: Wenn etwas vorhanden ist , würde Antwort invertiert werden: ( crtState >> 4 ) * -1 + 1
.
und das letzte Drehbuch:
#!/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
WARNUNGEN: Leichter als xrandr
, aber nicht unwichtig mit einer Verzögerung von weniger als 0,02 Sekunden. Das Bash-Skript springt an die Spitze des Ressourcenfresser-Prozesses ( top
)!
Während dies ~ 0,001 Sek. Kostet:
$ time read -a </proc/stat crtStat
Dies erfordert ~ 0,030 Sekunden:
$ read -a < /proc/acpi/video/VID/CRT0/state crtState
Das ist groß! Also je nachdem, was Sie brauchen, delay
könnte einigermaßen zwischen 0.5
und gesetzt werden 2
.
EDIT # 2
Ich habe endlich etwas gefunden, mit diesem:
Wichtiger Hinweis: Das Spielen mit /proc
und die /sys
Einträge können Ihr System beschädigen !!! Versuchen Sie Folgendes nicht auf Produktionssystemen.
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
... nach einigem Reinigen von unerwünschten Einträgen:
for ((i=0;i<=${#watchFileList[@]};i++)); do
[[ "${watchFileList[$i]}" =~ /sys/firmware/acpi/interrupts/sci ]] &&
unset watchFileList[$i] && echo $i
done
Ich konnte Folgendes lesen:
/proc/acpi/video/VID/CRT0/state:state: 0x1d
/proc/acpi/video/VID/CRT0/state:state: 0x0d
/proc/acpi/video/VID/CRT0/state:state: 0x1d
Wenn ich das Monitorkabel einstecke, ausziehe und wieder einstecke.
Ursprüngliche Antwort
Wenn die Konfiguration abgefragt wird (läuft system/preferences/monitor
oder xrandr
), führen Grafikkarten eine Art Scan durch , so dass beim Ausführen xrandr -q
die Informationen angezeigt werden, der Status jedoch abgefragt werden muss .
Ich habe alle Protokolle (Kernel, Daemon, X usw.) durchsucht und /proc
& durchsucht /sys
, und es scheint offensichtlich nichts zu geben, das Ihre Anfrage erfüllt.
Ich habe es auch versucht:
export spc50="$(printf "%50s" "")"
watch -n1 '
find /proc/acpi/video -type f |
xargs grep -H . |
sed "s/^\([^:]*):/\1'$spc50'}:/;
s/^\(.\{50\}\) *:/\1 /"'
Nach all dem wird System/Preferences/Monitor
das Tool einfach (normalerweise) angezeigt , wenn Sie ausführen, während noch kein neuer Bildschirm eingesteckt oder ausgesteckt wurde. Wenn Sie zuvor einen Bildschirm ein- oder ausgesteckt haben, führen Sie dieses Tool gelegentlich aus, und auf Ihrem Desktop wird eine Art Zurücksetzen oder Aktualisieren ausgeführt (dies gilt auch für den Fall, dass Sie einen Bildschirm ausführen xrandr
).
Dies scheint zu bestätigen, dass dieses Tool nach dem xrandr
Status fragt (oder auf die gleiche Weise funktioniert), indem es diesen regelmäßig abruft, beginnend zum Zeitpunkt seiner Ausführung.
Du könntest es selbst versuchen:
$ for ((i=10;i--;)); do xrandr -q | grep ' connected' | wc -l; sleep 1; done
1
1
1
2
2
2
1
1
1
1
Dies zeigt für 10 Sekunden an, wie viele Bildschirme (Displays) verbunden sind.
Während dies läuft, stecken Sie Ihren Bildschirm / Monitor ein und / oder aus und schauen, was passiert. So können Sie eine kleine Bash-Testfunktion erstellen:
isVgaConnected() {
local xRandr=$(xrandr -q)
[ "$xRandr" == "${xRandr#*VGA1 con}" ] || return 0
return 1
}
das wäre verwendbar wie in:
$ if isVgaConnected; then echo yes; fi
Aber seien Sie vorsichtig, es xrandr
dauert ungefähr 0,140 Sekunden bis 0,200 Sekunden, während sich an den Steckern nichts ändert, und bis zu 0,700 Sekunden, wenn etwas kurz zuvor eingesteckt oder abgezogen wurde ( HINWEIS: Es scheint kein Ressourcenfresser zu sein).
EDIT # 1
Um sicherzustellen, dass ich nichts Falsches unterrichte, habe ich im Web und in den Dokumenten gesucht, aber nichts über DBus und Bildschirme gefunden .
Schließlich habe ich in zwei verschiedenen Fenstern dbus-monitor --system
(ich habe auch mit Optionen gespielt) und dem kleinen Skript, das ich geschrieben habe, ausgeführt:
$ for ((i=1000;i--;)); do isVgaConnected && echo yes || echo no; sleep .5; done
... und steckte den Monitor wieder ein, dann steckte er ihn wieder aus. So jetzt könnte ich sagen:
- In dieser Konfiguration i915 - Treiber verwendet , gibt es keine andere Möglichkeit , als das Laufen
xrandr -q
zu wissen , ob ein Monitor angeschlossen ist oder nicht.
Aber seien Sie vorsichtig, denn es scheint keine anderen Möglichkeiten zu geben. Zum Beispiel xrandr
scheint diese Information zu teilen, so dass mein GNOME-Desktop xinerama
automatisch auf ... umschaltet, wenn ich liefxrandr
.
Einige Dokumente