नोट: यह एक i915 संचालित ग्राफिक्स कार्ड के साथ एक लैपटॉप पर परीक्षण किया गया था।
पृष्ठभूमि
नोट: जब एक नई स्क्रीन प्लग की जाती है, तो कोई भी आयोजन होस्ट को नहीं भेजा जाता है, यह मेरे अंतिम संपादन के बाद भी सही रहा। इसलिए एकमात्र तरीका मतदान का उपयोग करना है। जितना संभव हो उतने ही सहज बनाने की कोशिश ...
EDIT # 3
अंत में एक बेहतर समाधान है (ACPI के माध्यम से):
अभी भी कोई घटना नहीं है, लेकिन ACPI xrandrपूछताछ करने की तुलना में अधिक कुशल लगता है । (नोट: इसके लिए एसीपीआई कर्नेल मॉड्यूल लोड किए गए हैं, लेकिन रूट विशेषाधिकारों की आवश्यकता नहीं है)।
मेरा अंतिम समाधान (बाश का उपयोग करके):
isVgaConnected() {
local crtState
read -a < /proc/acpi/video/VID/CRT0/state crtState
test $(( ( ${crtState[1]} >>4 ) ${1:+*-1+1} )) -ne 0
}
अब एक परीक्षण:
$ if isVgaConnected; then echo yes; else echo no; fi
yes
इसमें प्लग किया गया है, इसलिए अब मैं इसे अनप्लग करता हूं:
$ if isVgaConnected; then echo yes; else echo no; fi
no
नोट: ${1:+*-1+1} एक बूलियन तर्क की अनुमति दें: यदि कुछ मौजूद है , तो उत्तर उल्टा होगा ( crtState >> 4 ) * -1 + 1:।
और अंतिम स्क्रिप्ट:
#!/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
चेतावनी: लाइटर की तुलना में xrandr, लेकिन 0.02 सेकंड से कम की देरी के साथ महत्वहीन नहीं , बैश स्क्रिप्ट संसाधन खाने वालों की प्रक्रिया के शीर्ष पर जाएगी ( top)!
जबकि यह लागत ~ 0.001 सेकंड है:
$ time read -a </proc/stat crtStat
इसके लिए ~ 0.030 सेकंड की आवश्यकता है:
$ read -a < /proc/acpi/video/VID/CRT0/state crtState
यह बड़ा है! तो आप क्या जरूरत पर निर्भर करता है, delayयथोचित 0.5और के बीच सेट किया जा सकता है 2।
EDIT # 2
मैंने आखिरकार, इसका उपयोग करते हुए कुछ पाया है:
महत्वपूर्ण अस्वीकरण: साथ खेलना /procऔर /sysप्रविष्टियां आपके सिस्टम को तोड़ सकती हैं !!! तो उत्पादन प्रणाली पर निम्नलिखित की कोशिश मत करो।
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
... अवांछित प्रविष्टि की कुछ सफाई के बाद:
for ((i=0;i<=${#watchFileList[@]};i++)); do
[[ "${watchFileList[$i]}" =~ /sys/firmware/acpi/interrupts/sci ]] &&
unset watchFileList[$i] && echo $i
done
मैं इसे पढ़ पा रहा हूं:
/proc/acpi/video/VID/CRT0/state:state: 0x1d
/proc/acpi/video/VID/CRT0/state:state: 0x0d
/proc/acpi/video/VID/CRT0/state:state: 0x1d
जब मैं प्लग, अनप्लग, और मॉनिटर केबल में फिर से भरना।
मूल उत्तर
जब कॉन्फिगर की पूछताछ (रनिंग system/preferences/monitorया xrandr) की जाती है, तो ग्राफिक्स कार्ड एक प्रकार का स्कैन करते हैं , इसलिए रनिंग xrandr -qआपको इसकी जानकारी देता है, लेकिन आपको स्टेटस को प्रदूषित करना होगा।
मैं सभी लॉग, (कर्नेल, डेमॉन, एक्स और आगे) के माध्यम से खोज स्कैन किया है /procऔर /sys, और स्पष्ट रूप से कुछ भी नहीं अस्तित्व के लिए, जो आपके अनुरोध को संतुष्ट करता है लगता है।
मैंने यह भी कोशिश की है:
export spc50="$(printf "%50s" "")"
watch -n1 '
find /proc/acpi/video -type f |
xargs grep -H . |
sed "s/^\([^:]*):/\1'$spc50'}:/;
s/^\(.\{50\}\) *:/\1 /"'
आखिरकार, यदि आप चलाते हैं, System/Preferences/Monitorजबकि कोई नई स्क्रीन अभी प्लग नहीं की गई है, और न ही अनप्लग की गई है, तो टूल बस (सामान्य रूप से) दिखाई देगा। लेकिन अगर आपने किसी स्क्रीन को पहले प्लग या अनप्लग किया है, तो कई बार आप इस टूल को चलाएंगे और आप देखेंगे कि आपका डेस्कटॉप एक प्रकार का रीसेट या रिफ्रेश (जैसा कि आप चलाते हैं xrandr) करते हैं।
यह पुष्टि करता है कि यह उपकरण xrandrसमय-समय पर मतदान की स्थिति के अनुसार (या उसी तरीके से काम करता है), जिस समय इसे चलाया जाता है, शुरू होता है।
आप खुद कोशिश कर सकते हैं:
$ for ((i=10;i--;)); do xrandr -q | grep ' connected' | wc -l; sleep 1; done
1
1
1
2
2
2
1
1
1
1
यह प्रदर्शित करेगा कि 10 सेकंड के लिए कितने स्क्रीन (डिस्प्ले) जुड़े हुए हैं।
जबकि यह चलता है, प्लग और / या अपनी स्क्रीन को अनप्लग करें / मॉनिटर करें और देखें कि क्या होता है। तो आप थोड़ा बैश टेस्ट फंक्शन बना सकते हैं:
isVgaConnected() {
local xRandr=$(xrandr -q)
[ "$xRandr" == "${xRandr#*VGA1 con}" ] || return 0
return 1
}
जो के रूप में प्रयोग करने योग्य होगा:
$ if isVgaConnected; then echo yes; fi
लेकिन सावधान रहें, xrandrलगभग 0.140 सेकंड से 0.200 सेकंड तक का समय लगता है जबकि प्लग में कोई परिवर्तन नहीं होता है और 0.700 सेकंड तक जब भी कुछ प्लग किया गया था या अनप्लग किया गया था ( नोट: ऐसा लगता है कि संसाधन भक्षक नहीं है)।
EDIT # 1
यह सुनिश्चित करने के लिए कि मैं कुछ गलत नहीं सिखा रहा हूं, मैंने वेब और डॉक्स के आसपास खोज की है, लेकिन डीबस और स्क्रीन के बारे में कुछ नहीं पाया ।
अंत में, मैं दो अलग-अलग विंडो में चला गया dbus-monitor --systemहूं (मैं विकल्पों के साथ भी खेल रहा हूं) और छोटी स्क्रिप्ट जो मैंने लिखी है:
$ for ((i=1000;i--;)); do isVgaConnected && echo yes || echo no; sleep .5; done
... और फिर से प्लग, अनप्लग किए गए मॉनिटर की तुलना में, कई बार। तो अब मैं कह सकता था:
- इस कॉन्फ़िगरेशन में, i915 ड्राइवर का उपयोग करते हुए , यह
xrandr -qजानने के लिए दौड़ने के अलावा कोई अन्य तरीका नहीं है कि कोई मॉनिटर प्लग किया गया है या नहीं।
लेकिन सावधानी बरतें, क्योंकि अन्य तरीके नहीं दिखते। उदाहरण के लिए, xrandrइस जानकारी को साझा करना प्रतीत होता है, इसलिए मेरा गनोम डेस्कटॉप xineramaस्वचालित रूप से स्विच हो जाएगा ... जब मैं भाग गयाxrandr ।
कुछ डॉक्स