LƯU Ý: Điều này đã được thử nghiệm trên máy tính xách tay với card đồ họa điều khiển i915.
Lý lịch
LƯU Ý: Khi một màn hình mới được cắm, không có sự kiện nào được gửi đến máy chủ, điều này vẫn đúng ngay cả sau lần chỉnh sửa cuối cùng của tôi. Vì vậy, cách duy nhất là sử dụng bỏ phiếu. Cố gắng làm cho chúng hiệu quả nhất có thể ...
EDIT # 3
Cuối cùng, có một giải pháp tốt hơn (thông qua ACPI):
Vẫn không có sự kiện, nhưng ACPI có vẻ hiệu quả hơn là xrandr
tìm hiểu. (Nota: Điều này yêu cầu các mô-đun hạt nhân ACPI được tải, nhưng không yêu cầu quyền root).
Giải pháp cuối cùng của tôi (sử dụng bash):
isVgaConnected() {
local crtState
read -a < /proc/acpi/video/VID/CRT0/state crtState
test $(( ( ${crtState[1]} >>4 ) ${1:+*-1+1} )) -ne 0
}
Bây giờ là một bài kiểm tra:
$ if isVgaConnected; then echo yes; else echo no; fi
yes
Nó đã được cắm, vì vậy bây giờ tôi rút phích cắm:
$ if isVgaConnected; then echo yes; else echo no; fi
no
LƯU Ý: cho ${1:+*-1+1}
phép một đối số boolean : Nếu có gì đó , câu trả lời sẽ được đảo ngược : ( crtState >> 4 ) * -1 + 1
.
và kịch bản cuối cùng:
#!/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
CẢNH BÁO: nhẹ hơn xrandr
, nhưng không quan trọng với độ trễ nhỏ hơn 0,02 giây, tập lệnh Bash sẽ đi đầu trong quá trình ăn tài nguyên ( top
)!
Trong khi chi phí này ~ 0,001 giây:
$ time read -a </proc/stat crtStat
Điều này cần ~ 0,030 giây:
$ read -a < /proc/acpi/video/VID/CRT0/state crtState
Thứ này lớn! Vì vậy, tùy thuộc vào những gì bạn cần, delay
có thể được đặt hợp lý giữa 0.5
và 2
.
EDIT # 2
Cuối cùng tôi đã tìm thấy một cái gì đó, bằng cách sử dụng này:
Từ chối trách nhiệm quan trọng: Chơi với /proc
và /sys
các mục có thể phá vỡ hệ thống của bạn !!! Vì vậy, đừng thử những điều sau đây trên các hệ thống sản xuất.
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
... Sau khi dọn dẹp các mục không mong muốn:
for ((i=0;i<=${#watchFileList[@]};i++)); do
[[ "${watchFileList[$i]}" =~ /sys/firmware/acpi/interrupts/sci ]] &&
unset watchFileList[$i] && echo $i
done
Tôi đã có thể đọc điều này:
/proc/acpi/video/VID/CRT0/state:state: 0x1d
/proc/acpi/video/VID/CRT0/state:state: 0x0d
/proc/acpi/video/VID/CRT0/state:state: 0x1d
Khi tôi cắm, rút phích cắm và cắm lại vào cáp màn hình.
Câu trả lời gốc
Khi cấu hình được hỏi (đang chạy system/preferences/monitor
hoặc xrandr
), các card đồ họa thực hiện một kiểu quét , do đó, việc chạy xrandr -q
sẽ cung cấp cho bạn thông tin, nhưng bạn phải thăm dò trạng thái.
Tôi đã quét tất cả các bản ghi, (kernel, daemon, X, v.v.) tìm kiếm thông qua /proc
& /sys
, và rõ ràng dường như không có gì tồn tại thỏa mãn yêu cầu của bạn.
Tôi cũng đã thử điều này:
export spc50="$(printf "%50s" "")"
watch -n1 '
find /proc/acpi/video -type f |
xargs grep -H . |
sed "s/^\([^:]*):/\1'$spc50'}:/;
s/^\(.\{50\}\) *:/\1 /"'
Sau tất cả, nếu bạn chạy System/Preferences/Monitor
trong khi không có màn hình mới vừa được cắm, cũng không được rút ra, công cụ sẽ xuất hiện đơn giản (bình thường). Nhưng nếu bạn đã cắm hoặc rút màn hình trước đó, đôi khi bạn sẽ chạy công cụ này và bạn sẽ thấy máy tính để bàn của mình thực hiện kiểu đặt lại hoặc làm mới (giống như khi bạn chạy xrandr
).
Điều này dường như xác nhận rằng công cụ này yêu cầu xrandr
(hoặc hoạt động theo cách tương tự) bằng cách bỏ phiếu theo trạng thái định kỳ, bắt đầu từ thời điểm nó chạy.
Bạn có thể tự thử:
$ for ((i=10;i--;)); do xrandr -q | grep ' connected' | wc -l; sleep 1; done
1
1
1
2
2
2
1
1
1
1
Điều này sẽ hiển thị số lượng màn hình (màn hình) được kết nối, trong 10 giây.
Trong khi điều này chạy, cắm và / hoặc rút phích cắm màn hình / màn hình của bạn và xem điều gì sẽ xảy ra. Vì vậy, bạn có thể tạo một hàm kiểm tra Bash nhỏ:
isVgaConnected() {
local xRandr=$(xrandr -q)
[ "$xRandr" == "${xRandr#*VGA1 con}" ] || return 0
return 1
}
có thể sử dụng như trong:
$ if isVgaConnected; then echo yes; fi
Nhưng hãy cẩn thận, xrandr
mất khoảng 0.140 giây đến 0.200 giây trong khi không có thay đổi nào xảy ra đối với phích cắm và tối đa 0,700 giây mỗi khi có thứ gì đó được cắm hoặc rút phích cắm ngay trước đó ( LƯU Ý: Có vẻ như không phải là người ăn tài nguyên).
EDIT # 1
Để đảm bảo tôi không dạy điều gì đó không chính xác, tôi đã tìm kiếm trên Web và các tài liệu, nhưng không tìm thấy gì về DBus và Screens .
Cuối cùng, tôi đã chạy trong hai cửa sổ khác nhau dbus-monitor --system
(tôi cũng đã chơi với các tùy chọn) và kịch bản nhỏ tôi đã viết:
$ for ((i=1000;i--;)); do isVgaConnected && echo yes || echo no; sleep .5; done
... và một lần nữa cắm, hơn là rút phích cắm màn hình, nhiều lần. Vì vậy, bây giờ tôi có thể nói:
- Trong cấu hình này, sử dụng trình điều khiển i915 , không có cách nào khác ngoài chạy
xrandr -q
để biết màn hình có được cắm hay không.
Nhưng hãy cẩn thận, vì dường như không có cách nào khác. Chẳng hạn, xrandr
dường như chia sẻ thông tin này, vì vậy máy tính để bàn Gnome của tôi sẽ xinerama
tự động chuyển sang ... khi tôi chạyxrandr
.
Một số tài liệu