basılan sağ ok tuşunu algılayan bashscript


Yanıtlar:


16

İki bayttan önce (büyük olasılıkla) okursunuz. $keycodebetiğinizde ok tuşuna basıldığında ESC olur.

Ok tuşları şunlar olabilir:

\x1b + some value

Koşullu ifadedeki eksik boşluklar nedeniyle daima doğru olarak değerlendirilir.

Düzenle: söz konusu ifadeyle ilgili bir güncelleme.

Sizin ifçıkış durumuna ilişkin faaliyet [komutu. [Komut eşdeğerdir test. Bir emir olması çok önemli bir gerçektir. Komut olarak, argümanlar arasında boşluk gerektirir. [Komut o gerektirir daha özeldir ]son argüman olarak.

[ EXPRESSION ]

Komut, EXPRESSION tarafından belirlenen durumla çıkar. 1 veya 0, doğru veya yanlış .

Öyle değil yazma parantez için egzotik bir yol. Başka bir deyişle, örneğin C'deki sözdiziminin bir parçası değildirif :

if (x == 39)

Tarafından:

if [ "$keycode"=39 ]; then

sorun:

[ "$keycode"=39 ]

hangi genişler

[ \x1b=39 ]

burada bir argüman \x1b=39olarak okunur . Ne zaman ya da verilir tek argüman o false ile çıkar yalnızca İFADE null - asla olacak olan. Boş olsa bile sonuçlanır (boş / boş değildir).test[$keycode=39

Buna bakmanın bir başka yolu da şöyle diyorsunuz:

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

Bu soruları ve cevapları Daha fazla ayrıntı için oku - yanı sıra tartışma [vs [[:

Bu bağlamda, keneleri de araştırabilirsiniz `` vs $( )


Ok tuşları ile çok baytlı kaçış dizisi:

Yukarıda belirtildiği gibi: Siz (muhtemelen) önce iki + bayttan birini okudunuz. $keycodebetiğinizde ok tuşuna basıldığında ESC olur.

Ok ve diğer özel tuşlar , sisteme kaçış dizilerinin gönderilmesine neden olur. ESC bayt sinyalleri olduğunu "Burada farklı yorumlanmalı bazı bayt gelir" . ASCII olacağını ok tuşlarıyla gelince [ASCII ardından A, B, Cveya D.

Başka bir deyişle, ok tuşlarıyla uğraşırken üç bayt ayrıştırmanız gerekir.

Kontrol etmek için bunun yönünde bir şey deneyebilirsiniz:

{   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

Yol ver:

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

Bunun ne kadar taşınabilir olduğundan emin değilim, ancak daha önce ok tuşlarını yakalamak için böyle bir kodla oynadın. Çıkmak qiçin tuşuna basın :

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

(Küçük not olarak da () için ondalık 39 karşı testini niyetinde -. Onluk ve onaltılık arasında bir mixup gibi görünüyor bir çıkış sırası İlk bayt olan ASCII değeri ESC olduğunu ondalık 27 ve onaltılık 0x1biken ondalık 39 onaltılık olduğunu 0x27. )


2
Sorudaki ilk sorun =, testteki işareti çevreleyen boşluk olmamasıdır , bu nedenle boş olmayan bir dize olarak ayrıştırılır ve bu nedenle doğrudur. Ok tuşlarının birden çok bayt olması ayrı bir konudur.
wurtel

2
Hmm, bu cümlenin olduğu gibi çok fazla bağlamı yok, bunu zaten bildiğim çok baytlı dizilerin açıklamasının bir parçası olduğunu düşündüğüm gibi okudum.
wurtel

2
@ wurtel: Evet. Belirsiz olmak için sanırım. Bir kez açıklamak [yerleşik bir komut olduğunu bulmak insanlar boşluk çok daha hızlı neden önemli kavramak. (Parantez yerine parantez kullanmak garip bir yöntem değildir.) Şimdi tükenmek zorunda. Bir kez daha güncelleyin.
user367890
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.