คุณ (เป็นไปได้) อ่านก่อนจากสอง + ไบต์ $keycode
ในสคริปต์ของคุณจะเป็น ESC เมื่อกดปุ่มลูกศร
ปุ่มลูกศรสามารถ:
\x1b + some value
มันมักจะประเมินว่าเป็นจริงเพราะช่องว่างที่ขาดหายไปในการแสดงออกตามเงื่อนไข
แก้ไข: การปรับปรุงคำสั่งนั้น
คุณif
ทำงานกับสถานะทางออกของ[
คำสั่ง คำสั่งเทียบเท่ากับ[
test
ความจริงที่ว่ามันเป็นคำสั่งเป็นข้อเท็จจริงที่สำคัญมาก ในฐานะที่เป็นคำสั่งมันต้องมีช่องว่างระหว่างข้อโต้แย้ง [
คำสั่งพิเศษเพิ่มเติมในการที่จะต้องใช้]
เป็นอาร์กิวเมนต์สุดท้าย
[ EXPRESSION ]
คำสั่งออกจากสถานะที่กำหนดโดย EXPRESSION 1 หรือ 0, จริงหรือเท็จ
มันไม่ใช่วิธีแปลกใหม่ในการเขียนวงเล็บ มันไม่ได้เป็นส่วนหนึ่งของif
ไวยากรณ์เช่นใน C:
if (x == 39)
โดย:
if [ "$keycode"=39 ]; then
คุณออก:
[ "$keycode"=39 ]
ซึ่งขยายเป็น
[ \x1b=39 ]
นี่\x1b=39
คือการอ่านเป็นหนึ่งอาร์กิวเมนต์ เมื่อtest
หรือ[
ได้รับหนึ่งอาร์กิวเมนต์มันจะออกด้วยเท็จเฉพาะในกรณีที่การแสดงออกเป็นโมฆะ - ซึ่งจะไม่เป็นไป แม้ว่าจะ$keycode
ว่างเปล่าก็จะส่งผลให้=39
(ซึ่งไม่เป็นโมฆะ / ว่างเปล่า)
อีกวิธีในการดูคือคุณพูดว่า:
if 0 ; then # When _command_ exit with 0.
if 1 ; then # When _command_ exit with 1.
อ่านคำถามและคำตอบสำหรับรายละเอียดเพิ่มเติมรวมถึงการอภิปรายเกี่ยว[
กับ vs [[
:
ในเรื่องนั้นคุณสามารถวิจัยย้อนกลับติ๊ก `` กับ $( )
ลำดับการหลบหลีกหลายไบต์พร้อมปุ่มลูกศร:
ดังที่กล่าวไว้ด้านบน: คุณ (น่าจะ) อ่านก่อนจากสองไบต์ $keycode
ในสคริปต์ของคุณจะเป็น ESC เมื่อกดปุ่มลูกศร
ลูกศรและปุ่มพิเศษอื่น ๆ ส่งผลให้escape sequencesถูกส่งไปยังระบบ ESCไบต์สัญญาณว่า"นี่มาไบต์บางอย่างที่ควรจะตีความที่แตกต่างกัน" สำหรับปุ่มลูกศรที่จะเป็นแอสกี[
ตาม ASCII A
, B
, หรือC
D
กล่าวอีกนัยหนึ่งคุณต้องแยกสามไบต์เมื่อจัดการกับปุ่มลูกศร
คุณสามารถลองบางสิ่งในทิศทางนี้เพื่อตรวจสอบ:
{ 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
ผลผลิต:
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
ไม่แน่ใจว่าเป็นอุปกรณ์พกพาได้อย่างไร แต่ก่อนหน้านี้ได้เล่นด้วยรหัสเช่นนี้เพื่อจับปุ่มลูกศร กดq
เพื่อออก:
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
(เป็นบันทึกเล็ก ๆ น้อย ๆ คุณยัง (ตั้งใจจะ) การทดสอบกับทศนิยม 39 -. ซึ่งมีลักษณะเหมือน Mixup ระหว่างทศนิยมและเลขฐานสิบหกไบต์ครั้งแรกในลำดับหนีเป็นค่า ASCII ESCซึ่งเป็นทศนิยม 27 และเลขฐานสิบหก0x1b
ในขณะทศนิยม 39 0x27
เป็นเลขฐานสิบหก)