NOTA: Isso foi testado em um laptop com uma placa gráfica i915.
fundo
NOTA: Quando uma nova tela é conectada, nenhum evento é enviado ao host, isso permanece verdadeiro mesmo após a minha última edição. Portanto, a única maneira é usar a pesquisa. Tentando torná-los o mais eficiente possível ...
EDIT # 3
Finalmente, há uma solução melhor (por meio da ACPI):
Ainda não há evento, mas a ACPI parece mais eficiente do xrandr
que perguntar. (Nota: isso requer módulos do kernel ACPI carregados, mas não requer privilégios de root).
Minha solução final (usando o bash):
isVgaConnected() {
local crtState
read -a < /proc/acpi/video/VID/CRT0/state crtState
test $(( ( ${crtState[1]} >>4 ) ${1:+*-1+1} )) -ne 0
}
Agora um teste:
$ if isVgaConnected; then echo yes; else echo no; fi
yes
Está conectado, então agora eu desconecto:
$ if isVgaConnected; then echo yes; else echo no; fi
no
NOTA: ${1:+*-1+1}
permitir um boolean argumento: Se algo está presente , a resposta seria invertido: ( crtState >> 4 ) * -1 + 1
.
e o script 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
Avisos: mais leve que xrandr
, mas não sem importância, com um atraso menor que 0,02 segundos, o script Bash irá para o topo do processo de obtenção de recursos ( top
)!
Enquanto isso custa ~ 0,001 seg:
$ time read -a </proc/stat crtStat
Isso requer ~ 0,030 seg:
$ read -a < /proc/acpi/video/VID/CRT0/state crtState
Isso é grande! Portanto, dependendo do que você precisa, delay
pode ser razoavelmente definido entre 0.5
e 2
.
EDIT # 2
Finalmente encontrei algo usando este:
Isenção de responsabilidade importante: Brincar com /proc
e /sys
entradas pode danificar seu sistema !!! Portanto, não tente o seguinte em sistemas de produção.
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
... após alguma limpeza de entradas indesejadas:
for ((i=0;i<=${#watchFileList[@]};i++)); do
[[ "${watchFileList[$i]}" =~ /sys/firmware/acpi/interrupts/sci ]] &&
unset watchFileList[$i] && echo $i
done
Eu pude ler isto:
/proc/acpi/video/VID/CRT0/state:state: 0x1d
/proc/acpi/video/VID/CRT0/state:state: 0x0d
/proc/acpi/video/VID/CRT0/state:state: 0x1d
Quando conecto, desconecto e conecto o cabo do monitor.
Resposta original
Quando a configuração é consultada (em execução system/preferences/monitor
ou xrandr
), as placas gráficas fazem um tipo de verificação ; portanto, a execução xrandr -q
fornece as informações, mas você precisa pesquisar o status.
Examinei todos os logs (kernel, daemon, X e assim por diante) pesquisando /proc
& /sys
, e claramente parece que não existe nada que satisfaça sua solicitação.
Eu tentei isso também:
export spc50="$(printf "%50s" "")"
watch -n1 '
find /proc/acpi/video -type f |
xargs grep -H . |
sed "s/^\([^:]*):/\1'$spc50'}:/;
s/^\(.\{50\}\) *:/\1 /"'
Depois de tudo isso, se você executar System/Preferences/Monitor
enquanto nenhuma nova tela foi conectada ou desconectada, a ferramenta aparecerá simplesmente (normalmente). Mas se você conectou ou desconectou uma tela antes, às vezes você executa esta ferramenta e vê sua área de trabalho fazendo um tipo de redefinição ou atualização (o mesmo se você executar xrandr
).
Isso parece confirmar que essa ferramenta solicita xrandr
(ou funciona da mesma maneira) pesquisando o status periodicamente, começando no momento em que é executada.
Você pode tentar:
$ for ((i=10;i--;)); do xrandr -q | grep ' connected' | wc -l; sleep 1; done
1
1
1
2
2
2
1
1
1
1
Isso exibirá quantas telas (monitores) estão conectadas por 10 segundos.
Enquanto isso estiver funcionando, conecte e / ou desconecte sua tela / monitor e veja o que está acontecendo. Então você pode criar uma pequena função de teste do Bash:
isVgaConnected() {
local xRandr=$(xrandr -q)
[ "$xRandr" == "${xRandr#*VGA1 con}" ] || return 0
return 1
}
que seria utilizável como em:
$ if isVgaConnected; then echo yes; fi
Mas tenha cuidado, xrandr
leva de 0,140 a 0,200 s enquanto nenhuma alteração ocorre nos plugues e até 0,700 segundos sempre que algo foi conectado ou desconectado pouco antes ( NOTA: parece não ser um consumidor de recursos).
EDIT # 1
Para garantir que não estou ensinando algo incorreto, pesquisei na Web e nos documentos, mas não encontrei nada sobre DBus e telas .
Finalmente, corri em duas janelas diferentes dbus-monitor --system
(também brinquei com opções) e o pequeno script que escrevi:
$ for ((i=1000;i--;)); do isVgaConnected && echo yes || echo no; sleep .5; done
... e novamente conectado, depois de desconectado o monitor, muitas vezes. Então agora eu poderia dizer:
- Nesta configuração, usando o driver i915 , não há outra maneira senão executar
xrandr -q
para saber se um monitor está conectado ou não.
Mas tenha cuidado, porque não parece haver outras maneiras. Por exemplo, xrandr
parece compartilhar essas informações, então minha área de trabalho do GNOME mudaria para xinerama
automaticamente ... quando eu corriaxrandr
.
Alguns documentos