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.