İ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. )