NOTA: Esto se probó en una computadora portátil con una tarjeta gráfica impulsada por i915.
Antecedentes
NOTA: Cuando se conecta una nueva pantalla, no se envía ningún evento al host, esto se mantuvo incluso después de mi última edición. Entonces, la única forma es usar encuestas. Tratando de hacerlos lo más eficientes posible ...
EDITAR # 3
Finalmente hay una mejor solución (a través de ACPI):
Todavía no hay ningún evento, pero ACPI parece más eficiente que xrandr
preguntar. (Nota: Esto requiere que se carguen los módulos del núcleo ACPI, pero no requiere privilegios de root).
Mi solución final (usando bash):
isVgaConnected() {
local crtState
read -a < /proc/acpi/video/VID/CRT0/state crtState
test $(( ( ${crtState[1]} >>4 ) ${1:+*-1+1} )) -ne 0
}
Ahora una prueba:
$ if isVgaConnected; then echo yes; else echo no; fi
yes
Está enchufado, así que ahora lo desconecto:
$ if isVgaConnected; then echo yes; else echo no; fi
no
NOTA: ${1:+*-1+1}
permite que un booleano argumento: si algo está presente , se invierte la respuesta: ( crtState >> 4 ) * -1 + 1
.
y el guión final:
#!/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
ADVERTENCIAS: más ligero xrandr
, pero no sin importancia con un retraso menor a 0.02 segundos, ¡el script Bash irá a la parte superior del proceso de comedores de recursos ( top
)!
Si bien esto cuesta ~ 0.001 segundos:
$ time read -a </proc/stat crtStat
Esto requiere ~ 0.030 segundos:
$ read -a < /proc/acpi/video/VID/CRT0/state crtState
¡Esto es grande! Entonces, dependiendo de lo que necesite, delay
podría establecerse razonablemente entre 0.5
y 2
.
EDITAR # 2
Finalmente encontré algo, usando esto:
Descargo de responsabilidad importante: ¡ Jugar con /proc
y /sys
entradas podría dañar su sistema! Así que no intentes lo siguiente en sistemas de producción.
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
... después de una limpieza de entradas no deseadas:
for ((i=0;i<=${#watchFileList[@]};i++)); do
[[ "${watchFileList[$i]}" =~ /sys/firmware/acpi/interrupts/sci ]] &&
unset watchFileList[$i] && echo $i
done
He podido leer esto:
/proc/acpi/video/VID/CRT0/state:state: 0x1d
/proc/acpi/video/VID/CRT0/state:state: 0x0d
/proc/acpi/video/VID/CRT0/state:state: 0x1d
Cuando conecto, desconecto y vuelvo a enchufar el cable del monitor.
Respuesta original
Cuando se consulta la configuración (en ejecución system/preferences/monitor
o xrandr
), las tarjetas gráficas realizan un tipo de exploración , por lo que la ejecución le xrandr -q
brinda la información, pero debe sondear el estado.
He escaneado todos los registros (kernel, daemon, X, etc.) buscando en /proc
& /sys
, y claramente parece que no existe nada que satisfaga su solicitud.
También he intentado esto:
export spc50="$(printf "%50s" "")"
watch -n1 '
find /proc/acpi/video -type f |
xargs grep -H . |
sed "s/^\([^:]*):/\1'$spc50'}:/;
s/^\(.\{50\}\) *:/\1 /"'
Después de todo eso, si ejecuta System/Preferences/Monitor
mientras no se ha enchufado una nueva pantalla, ni se ha desenchufado, la herramienta aparecerá simplemente (normalmente). Pero si ha conectado o desconectado una pantalla anteriormente, a veces ejecutará esta herramienta y verá que su escritorio realiza un tipo de reinicio o actualización (lo mismo si ejecuta xrandr
).
Esto parece confirmar que esta herramienta solicita xrandr
(o funciona de la misma manera) al sondear el estado periódicamente, comenzando en el momento en que se ejecuta.
Podrías probarlo tú mismo:
$ for ((i=10;i--;)); do xrandr -q | grep ' connected' | wc -l; sleep 1; done
1
1
1
2
2
2
1
1
1
1
Esto mostrará cuántas pantallas (pantallas) están conectadas, durante 10 segundos.
Mientras esto se ejecuta, conecte y / o desconecte su pantalla / monitor y vea lo que sucede. Para que pueda crear una pequeña función de prueba de Bash:
isVgaConnected() {
local xRandr=$(xrandr -q)
[ "$xRandr" == "${xRandr#*VGA1 con}" ] || return 0
return 1
}
que sería utilizable como en:
$ if isVgaConnected; then echo yes; fi
Pero tenga cuidado, xrandr
toma alrededor de 0.140 segundos a 0.200 segundos mientras no se produce ningún cambio en los enchufes y hasta 0.700 segundos cada vez que algo se conectó o desconectó justo antes ( NOTA: Parece que no consume recursos).
EDITAR # 1
Para asegurarme de que no estoy enseñando algo incorrecto, busqué en la Web y en los documentos, pero no encontré nada sobre DBus y pantallas .
Finalmente, corrí en dos ventanas diferentes dbus-monitor --system
(también he estado jugando con opciones) y el pequeño script que escribí:
$ for ((i=1000;i--;)); do isVgaConnected && echo yes || echo no; sleep .5; done
... y nuevamente enchufado, que desenchufó el monitor, muchas veces. Entonces ahora podría decir:
- En esta configuración, usando el controlador i915 , no hay otra manera que ejecutar
xrandr -q
para saber si un monitor está enchufado o no.
Pero tenga cuidado, porque no parece haber otras formas. Por ejemplo, xrandr
parece compartir esta información, por lo que mi escritorio GNOME cambiará xinerama
automáticamente ... cuando ejecutéxrandr
.
Algunos documentos