Anda (kemungkinan) membaca pertama dari dua + byte. $keycode
dalam skrip Anda akan menjadi ESC ketika tombol panah ditekan.
Tombol panah dapat:
\x1b + some value
Itu selalu bernilai true karena ruang yang hilang dalam ekspresi bersyarat.
Edit: pembaruan pada pernyataan itu.
Anda if
beroperasi pada status keluar dari [
perintah. The [
perintah setara dengan test
. Fakta bahwa itu adalah perintah adalah fakta yang sangat penting. Sebagai perintah itu membutuhkan spasi di antara argumen. The [
perintah khusus lebih lanjut dalam hal itu membutuhkan ]
sebagai argumen terakhir.
[ EXPRESSION ]
Perintah keluar dengan status yang ditentukan oleh EXPRESSION. 1 atau 0, benar atau salah .
Ini bukan cara eksotis untuk menulis kurung. Dengan kata lain itu bukan bagian dari if
sintaksis seperti misalnya dalam C:
if (x == 39)
Oleh:
if [ "$keycode"=39 ]; then
Anda mengeluarkan:
[ "$keycode"=39 ]
yang diperluas ke
[ \x1b=39 ]
di sini \x1b=39
dibaca sebagai satu argumen. Ketika test
atau [
diberikan satu argumen ia keluar dengan false hanya jika EXPRESSION adalah null - yang tidak akan pernah terjadi. Bahkan jika $keycode
kosong, itu akan menghasilkan =39
(yang bukan nol / kosong).
Cara lain untuk melihatnya adalah dengan mengatakan:
if 0 ; then # When _command_ exit with 0.
if 1 ; then # When _command_ exit with 1.
Baca pertanyaan dan jawaban ini untuk lebih jelasnya - serta diskusi tentang [
vs [[
:
Dalam hal ini, Anda juga dapat meneliti kembali ticks `` vs $( )
Urutan melarikan diri multibyte dengan tombol panah:
Seperti disebutkan di atas: Anda (kemungkinan) membaca pertama dari dua + byte. $keycode
dalam skrip Anda akan menjadi ESC ketika tombol panah ditekan.
Panah dan kunci khusus lainnya menghasilkan urutan melarikan diri untuk dikirim ke sistem. The ESC byte sinyal bahwa "inilah beberapa byte yang harus ditafsirkan secara berbeda" . Adapun tombol panah yang akan menjadi ASCII yang [
diikuti oleh ASCII A
, B
, C
atau D
.
Dengan kata lain Anda harus mengurai tiga byte saat berurusan dengan tombol panah.
Anda dapat mencoba sesuatu ke arah ini untuk memeriksa:
{ 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
Menghasilkan:
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
Tidak yakin seberapa portabel ini, tetapi sebelumnya bermain-main dengan kode seperti ini untuk menangkap tombol panah. Tekan q
untuk berhenti:
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
(Sebagai catatan kecil Anda juga (bermaksud untuk) menguji terhadap desimal 39 - yang terlihat seperti campuran antara desimal dan heksadesimal. Byte pertama dalam urutan melarikan diri adalah nilai ASCII ESC , yang desimal 27 dan heksadesimal 0x1b
, sedangkan desimal 39 adalah heksadesimal 0x27
. )