OBSERVAÇÃO: Isso foi testado em um laptop com placa gráfica i915.
Antecedentes
OBSERVAÇÃO: Quando uma nova tela é conectada, nenhum evento é enviado ao host. Isso permanece verdadeiro mesmo depois da minha última edição. Então, a única maneira é usar o polling. Tentando torná-los tão eficientes quanto 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 que xrandr
para perguntar. (Nota: Este requer módulos do kernel da 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
Ele está conectado, então agora eu o desconecto:
$ if isVgaConnected; then echo yes; else echo no; fi
no
NOTA: ${1:+*-1+1}
permite um argumento booleano : Se algo estiver presente , a resposta seria invertida: ( crtState >> 4 ) * -1 + 1
.
e o roteiro 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 claro que xrandr
, mas não sem importância com um atraso menor que 0,02 segundos, o script Bash irá para o início do processo de comedores 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! Então, dependendo do que você precisa, delay
pode ser razoavelmente definido entre 0.5
e 2
.
Espero que esta ajuda!
EDIT # 2
Eu finalmente encontrei algo usando isso:
Aviso importante: Jogar com /proc
e /sys
entradas pode quebrar o 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 consegui 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 eu conecto, desconecto e reconecto no cabo do monitor.
Resposta Original Quando a configuração é consultada (executando system/preferences/monitor
ou xrandr
), as placas gráficas fazem um tipo de varredura , portanto, executar xrandr -q
fornece as informações, mas você precisa pesquisar o status.
Eu verifiquei todos os registros, (kernel, daemon, X e assim por diante) pesquisando /proc
& /sys
, e aparentemente nada parece existir que satisfaça seu pedido.
Eu também tentei isso:
export spc50="$(printf "%50s" "")"
watch -n1 '
find /proc/acpi/video -type f |
xargs grep -H . |
sed "s/^\([^:]*):/'$spc50'}:/;
s/^\(.\{50\}\) *:/ /"'
Depois de tudo isso, se você executar System/Preferences/Monitor
enquanto nenhuma nova tela acaba de ser conectada, nem desligada, a ferramenta aparecerá simplesmente (normalmente). Mas se você conectou ou desconectou uma tela antes, às vezes você executará esta ferramenta e verá sua área de trabalho fazendo um tipo de reset ou atualização (mesmo se você executar xrandr
).
Isso parece confirmar que essa ferramenta solicita xrandr
(ou funciona da mesma maneira) pelo status de sondagem 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 mostrará quantas telas (monitores) estão conectadas por 10 segundos.
Enquanto isso é executado, conecte e / ou desconecte sua tela / monitor e veja o que acontece. Então você pode criar uma pequena função de teste 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
demora cerca de 0,140 seg. a 0,200 seg. , enquanto não ocorre qualquer alteração nas fichas e até 0,700 segundos sempre que alguma coisa foi ligada ou desligada antes ( NOTA: parece não ser um comedor de recursos).
EDIT # 1
Para garantir que não estou ensinando algo incorreto, pesquisei na Web e em documentos, mas não encontrei nada sobre DBus e Telas .
Finalmente, eu corri em duas janelas diferentes dbus-monitor --system
(eu tenho jogado com opções também) e o pequeno script que eu escrevi:
$ for ((i=1000;i--;)); do isVgaConnected && echo yes || echo no; sleep .5; done
... e novamente conectado, do que desconectado do monitor, muitas vezes. Então agora eu poderia dizer:
- Nessa configuração, usando o driver i915 , não há outra maneira de 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 essa informação, então minha área de trabalho GNOME mudaria para xinerama
automaticamente ... quando eu corria xrandr
.