दायां तीर कुंजी का पता लगाने के लिए बैशस्क्रिप्ट दबाया जा रहा है


9

क्यों यह हमेशा सही के रूप में पता लगाता है, भले ही कीकोड सही-तीर-कुंजी न हो?

stty_state=`stty -g`
stty raw; stty -echo
keycode=`dd bs=1 count=1 2>/dev/null`
stty "$stty_state"  

echo $keycode

if [ "$keycode"=39 ]; then
echo "Right Arrow Key Pressed!"
fi

जवाबों:


16

आप (संभावना) दो + बाइट्स में से पहले पढ़ते हैं। $keycodeजब तीर कुंजी दबाया जाता है तो आपकी स्क्रिप्ट ईएससी होगी।

तीर कुंजी हो सकती है:

\x1b + some value

यह हमेशा सशर्त अभिव्यक्ति में रिक्त स्थान की वजह से सच का मूल्यांकन करता है।

संपादित करें: उस कथन पर एक अपडेट।

आपका कमांड ifके बाहर निकलने की स्थिति पर काम करता है [[आदेश के बराबर है test। तथ्य यह है कि यह एक है आदेश एक बहुत ही महत्वपूर्ण तथ्य है। एक आदेश के रूप में इसे तर्कों के बीच रिक्त स्थान की आवश्यकता होती है। [आदेश में यह अपेक्षा करते हैं कि आगे क्या खास बात है ]पिछले तर्क के रूप में।

[ EXPRESSION ]

आदेश अपवाद द्वारा निर्धारित स्थिति से बाहर निकलता है। १ या ०, सत्य या असत्य

यह कोष्ठक लिखने का एक विदेशी तरीका नहीं है। दूसरे शब्दों में यह C में उदाहरण के लिए वाक्यविन्यास का हिस्सा नहींif है:

if (x == 39)

द्वारा:

if [ "$keycode"=39 ]; then

आप जारी करें:

[ "$keycode"=39 ]

जिसका विस्तार होता है

[ \x1b=39 ]

यहाँ एक तर्क के \x1b=39रूप में पढ़ा जाता है। जब या एक तर्क दिया जाता है तो यह केवल झूठे के साथ बाहर निकलता है यदि अपवाद शून्य है - जो कभी नहीं होने वाला है। यहां तक ​​कि अगर खाली था, तो इसमें परिणाम होगा (जो शून्य / खाली नहीं है)।test[$keycode=39

इसे देखने का एक और तरीका यह है कि आप कहें:

if 0 ; then # When _command_ exit with 0.
if 1 ; then # When _command_ exit with 1.

अधिक विवरण के लिए ये प्रश्न और उत्तर पढ़ें - साथ ही [बनाम पर चर्चा [[:

उस संबंध में आप 'टिक' पर भी शोध कर सकते हैं $( )


तीर कुंजी के साथ मल्टीबाइट एस्केप सीक्वेंस:

जैसा कि शीर्ष पर उल्लेख किया गया है: आप (संभावना) दो + बाइट्स में से पहले पढ़ते हैं। $keycodeजब तीर कुंजी दबाया जाता है तो आपकी स्क्रिप्ट ईएससी होगी।

एरो और अन्य विशेष कुंजियों के परिणामस्वरूप सिस्टम को भेजे जाने वाले एस्केप सीक्वेंस होते हैं। ESC बाइट संकेत है कि "यहाँ कुछ बाइट्स कि अलग ढंग से व्याख्या की जानी चाहिए आता है" । तीर कुंजी है कि ASCII होगा के रूप में [द्वारा ASCII पीछा किया A, B, Cया D

दूसरे शब्दों में, आपको तीर कुंजी के साथ काम करते समय तीन बाइट्स को पार्स करना होगा।

आप इसे जांचने की दिशा में कुछ प्रयास कर सकते हैं:

{   stty_state=$(stty -g)
    stty raw isig -echo
    keycode=$(dd bs=8 conv=sync count=1)
    stty "$stty_state"
} </dev/tty 2>/dev/null
printf %s "$keycode" | xxd

प्राप्ति:

HEX        ASCII
1b 5b 41   .[A # Up arrow
1b 5b 42   .[B # Down arrow
1b 5b 43   .[C # Right arrow
1b 5b 44   .[D # Left arrow
 |  |  |
 |  |  +------ ASCII A, B, C and D
 |  +--------- ASCII [
 +------------ ASCII ESC

यह सुनिश्चित नहीं है कि यह कितना पोर्टेबल है, लेकिन पहले तीर कुंजी को पकड़ने के लिए इस तरह कोड के साथ खेला है। qछोड़ने के लिए दबाएँ :

while read -rsn1 ui; do
    case "$ui" in
    $'\x1b')    # Handle ESC sequence.
        # Flush read. We account for sequences for Fx keys as
        # well. 6 should suffice far more then enough.
        read -rsn1 -t 0.1 tmp
        if [[ "$tmp" == "[" ]]; then
            read -rsn1 -t 0.1 tmp
            case "$tmp" in
            "A") printf "Up\n";;
            "B") printf "Down\n";;
            "C") printf "Right\n";;
            "D") printf "Left\n";;
            esac
        fi
        # Flush "stdin" with 0.1  sec timeout.
        read -rsn5 -t 0.1
        ;;
    # Other one byte (char) cases. Here only quit.
    q) break;;
    esac
done

(एक छोटे नोट के रूप में आप दशमलव 39 के खिलाफ भी परीक्षण करना चाहते हैं) - जो दशमलव और हेमाडेसिमल के बीच मिश्रण की तरह दिखता है। भागने के क्रम में पहला बाइट एएससीआईआई मूल्य ईएससी है , जो दशमलव 27 और हेक्साडेसिमल है 0x1b, जबकि दशमलव 39 हेक्साडेसिमल है 0x27। )


2
प्रश्न में पहली समस्या यह है कि =परीक्षण में साइन के आसपास कोई रिक्त स्थान नहीं हैं , इसलिए इसे केवल एक गैर-रिक्त स्ट्रिंग के रूप में पार्स किया गया है और इसलिए यह सच है। तथ्य यह है कि तीर कुंजी कई बाइट्स हैं एक अलग मुद्दा है।
15:15

2
हम्म, उस वाक्य के रूप में ज्यादा संदर्भ नहीं है, मैंने पढ़ा है कि जैसा कि मैंने सोचा था कि मल्टी-बाइट अनुक्रमों के स्पष्टीकरण का हिस्सा था, जिसे मैं पहले से ही जानता था।
8

2
@ वत्सल: हाँ। अस्पष्ट करने के लिए मुझे लगता है। यह पता लगाएं कि एक बार समझाने [के बाद एक अंतर्निहित कमांड लोग समझ लेते हैं कि रिक्त स्थान अधिक महत्वपूर्ण क्यों हैं। (यह कोष्ठक के बजाय कोष्ठक का उपयोग करने के लिए बैश का एक अजीब तरीका नहीं है।) अब बाहर भागना है। एक बार अपडेट करें।
user367890
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.