Bạn (có khả năng) đọc đầu tiên trong số hai byte. $keycode
trong tập lệnh của bạn sẽ là ESC khi nhấn phím mũi tên.
Phím mũi tên có thể là:
\x1b + some value
Nó luôn luôn đánh giá là đúng vì thiếu khoảng trắng trong biểu thức điều kiện.
Chỉnh sửa: một bản cập nhật về tuyên bố đó.
if
Hoạt động của bạn trên trạng thái thoát [
lệnh. Các [
lệnh tương đương với test
. Thực tế đó là một lệnh là một thực tế rất quan trọng. Như một lệnh, nó yêu cầu khoảng trắng giữa các đối số. Các [
lệnh là đặc biệt hơn nữa ở chỗ nó đòi hỏi ]
như là đối số cuối cùng.
[ EXPRESSION ]
Lệnh thoát với trạng thái được xác định bởi EXPRESSION. 1 hoặc 0, đúng hay sai .
Nó không phải là một cách kỳ lạ để viết ngoặc đơn. Nói cách khác, nó không phải là một phần của if
cú pháp như trong C:
if (x == 39)
Bởi:
if [ "$keycode"=39 ]; then
bạn phát hành:
[ "$keycode"=39 ]
mở rộng ra
[ \x1b=39 ]
ở đây \x1b=39
được đọc như một đối số. Khi test
hoặc [
được đưa ra một đối số, nó sẽ thoát với false chỉ khi EXPRESSION là null - điều này sẽ không bao giờ xảy ra. Ngay cả khi $keycode
trống, nó sẽ dẫn đến =39
(không phải là null / rỗng).
Một cách khác để xem xét nó là bạn nói:
if 0 ; then # When _command_ exit with 0.
if 1 ; then # When _command_ exit with 1.
Đọc những câu hỏi và câu trả lời này để biết thêm chi tiết - cũng như thảo luận về [
vs [[
:
Về vấn đề đó, bạn cũng có thể nghiên cứu lại các dấu tick `` vs. $( )
Trình tự thoát đa nhân với các phím mũi tên:
Như đã đề cập ở trên cùng: Bạn (có thể) đọc đầu tiên trong số hai byte. $keycode
trong tập lệnh của bạn sẽ là ESC khi nhấn phím mũi tên.
Mũi tên và các phím đặc biệt khác dẫn đến các chuỗi thoát được gửi đến hệ thống. Các tín hiệu byte ESC "ở đây có một số byte nên được hiểu khác nhau" . Đối với các phím mũi tên sẽ là ASCII [
tiếp theo ASCII A
, B
, C
hoặc D
.
Nói cách khác, bạn phải phân tích ba byte khi xử lý các phím mũi tên.
Bạn có thể thử một cái gì đó theo hướng này để kiểm tra:
{ 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
Năng suất:
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
Không chắc chắn mức độ di động của nó, nhưng trước đó đã chơi xung quanh với mã như thế này để bắt các phím mũi tên. Nhấn q
để thoát:
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
(Là một phụ lưu ý bạn cũng (có ý định) kiểm tra đối với số thập phân 39 -. Mà trông giống như một mixup giữa số thập phân và thập lục phân byte đầu tiên trong một dãy thoát là giá trị ASCII ESC , đó là số thập phân 27 và thập lục phân 0x1b
, trong khi số thập phân 39 là thập lục phân 0x27
. )