1 คะแนน โดย GN⁺ 2024-07-09 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

ทำไมการป้อนข้อความในเทอร์มินัลจึงซับซ้อน

  • เมื่อถามผู้คนบน Mastodon ว่าอะไรทำให้พวกเขาสับสนเกี่ยวกับการทำงานบนเทอร์มินัล สิ่งที่เด่นชัดคือ "การแก้ไขคำสั่งที่พิมพ์ไปแล้ว"
  • ต้องการแบ่งปันว่าทำไมการป้อนข้อความในเทอร์มินัลจึงยาก และมีเคล็ดลับที่เป็นประโยชน์บางอย่าง

ความสม่ำเสมอที่ขาดหายไประหว่างโปรแกรมต่าง ๆ

  • วิธีที่โปรแกรมหลากหลายตัวจัดการการป้อนข้อความนั้นไม่สม่ำเสมอ
    • บางโปรแกรม (cat, nc, git commit --interactive เป็นต้น) ไม่รองรับปุ่มลูกศรเลย
    • หลายโปรแกรม (irb, python3 เป็นต้น) ใช้ไลบรารี readline เพื่อให้ความสามารถพื้นฐาน
    • บางโปรแกรมรองรับเพียงความสามารถพื้นฐาน
    • บางโปรแกรมมีระบบป้อนข้อมูลแบบคัสตอมทั้งหมด

โหมด 1: สถานะพื้นฐาน

  • สถานะพื้นฐานที่โปรแกรมเพียงรับการป้อนข้อความ
    • ให้ความสามารถพื้นฐาน เช่น การพิมพ์ข้อความ, backspace, Ctrl+W, Ctrl+U เป็นต้น
    • สามารถดู Ctrl code ทั้งหมดที่รองรับได้ด้วยคำสั่ง stty -a

โหมด 2: เครื่องมือที่ใช้ readline

  • readline เป็นไลบรารี GNU ที่ช่วยให้การป้อนข้อความสะดวกขึ้น
    • มีคีย์ลัดที่มีประโยชน์ เช่น Ctrl+E, Ctrl+A, Ctrl+left/right arrow, Ctrl+R
    • หลายโปรแกรม เช่น bash, psql, irb, python3 ใช้ readline

เคล็ดลับ: ใช้ rlwrap เพื่อใช้ readline

  • สามารถใช้ rlwrap เพื่อให้โปรแกรมที่ไม่รองรับ readline ใช้งานความสามารถของ readline ได้

ทำไมเครื่องมือถึงไม่ใช้ readline

  • เพราะโปรแกรมอาจเรียบง่ายมาก มีปัญหาเรื่องไลเซนส์ หรือมีปฏิสัมพันธ์น้อย เป็นต้น

วิธีตรวจสอบว่าใช้ readline หรือไม่

  • หากกด Ctrl+R แล้วมี reverse-i-search แสดงขึ้นมา ก็มีโอกาสสูงว่ากำลังใช้ readline อยู่

ที่มาของคีย์ไบน์ดิ้ง readline

  • คีย์ไบน์ดิ้งของ readline มีต้นกำเนิดมาจาก Emacs

โหมด 3: ไลบรารีป้อนข้อมูลอื่น ๆ (libedit เป็นต้น)

  • /usr/bin/python3 บน Mac ใช้ libedit จึงรองรับความสามารถของ readline ได้เพียงบางส่วน

โหมด 4: ระบบป้อนข้อมูลแบบคัสตอม

  • โปรแกรมแก้ไขข้อความอย่าง nano, micro, vim, emacs และเชลล์อย่าง fish มีระบบป้อนข้อมูลแบบคัสตอม
  • ระบบคัสตอมมักได้รับแรงบันดาลใจจาก readline

หลายเชลล์รองรับคีย์ไบน์ดิ้งแบบ vi

  • bash, zsh, fish เป็นต้น รองรับ "vi mode" สำหรับการป้อนข้อความ

การเข้าใจบริบทช่วยได้

  • เมื่อพิมพ์ข้อความที่ command line prompt หากเข้าใจบริบทก็จะคาดเดาได้มากขึ้นและสับสนน้อยลง

สิ่งที่บทความนี้ไม่ได้ครอบคลุม

  • ปัญหาที่เกี่ยวกับ ssh, tmux, ตัวแปรสภาพแวดล้อม TERM, การรองรับคัดลอก/วางของเทอร์มินัลหลายแบบ, Unicode เป็นต้น

สรุปโดย GN⁺

  • อธิบายว่าทำไมการป้อนข้อความในเทอร์มินัลจึงซับซ้อน และเหตุใดจึงขาดความสม่ำเสมอระหว่างโปรแกรมต่าง ๆ
  • แนะนำวิธีทำให้การป้อนข้อความสะดวกขึ้นด้วยไลบรารีอย่าง readline
  • ให้เคล็ดลับการเพิ่มความสามารถของ readline ด้วย rlwrap
  • เน้นย้ำว่าการเข้าใจบริบทระหว่างใช้งานเทอร์มินัลเป็นสิ่งสำคัญ

1 ความคิดเห็น

 
GN⁺ 2024-07-09
ความคิดเห็นบน Hacker News
  • บทความของ Julia ดีเสมอ

    • ใน shell script สามารถใช้ stty เพื่อเปลี่ยนวิธีที่เทอร์มินัลจัดการอินพุตได้
    • มีการแชร์การทดลองที่สามารถจับและทำความเข้าใจคีย์คอมบิเนชันและท่าทางเมาส์บนเทอร์มินัลที่เข้ากันได้กับ VT100
    • สามารถรันเดโมได้ด้วยคำสั่ง bash -c "$(curl -L https://git.io/fjToH)"
    • สามารถใช้ vi | cat -v เพื่อดู VT100 escape sequence ของโปรแกรมแบบโต้ตอบได้
  • สิ่งที่ขาดหายไปจากบทความ

    • wide character
    • ANSI escape sequence ที่แตกต่างกันตามโหมดคีย์บอร์ด
    • สถานะ TTY ที่หลากหลาย
    • system call สำหรับเปลี่ยนสถานะ TTY ที่แตกต่างกันไปในแต่ละ OS
    • ความแตกต่างของการรองรับ terminal emulation
    • การขาดฉันทามติเรื่องวิธีตรวจสอบความสามารถของเทอร์มินัล
  • หากตั้งค่า $EDITOR ใน bash ไว้ สามารถใช้ ctrl-x ctrl-e เพื่อส่งบรรทัดปัจจุบันไปยัง $EDITOR ได้

  • เมื่อ 20 ปีก่อนเคยสร้างตัวแก้ไขหลายบรรทัดโดยใช้ readline

    • รวมความสามารถในการวาดใหม่เมื่อย้ายเคอร์เซอร์และเมื่อขนาดเทอร์มินัลเปลี่ยน
    • อยากเขียนใหม่ด้วย Rust และปล่อยเป็นไลบรารีขนาดเล็ก
  • คำถามเกี่ยวกับวิธีการทำงานของฟังก์ชัน fgets()

    • โดยพื้นฐานแล้ว fgets() จะบล็อกจนกว่าผู้ใช้จะป้อนบรรทัดใหม่
    • สามารถแก้ไข line buffer ได้ด้วยปุ่มลัด Backspace, Ctrl+W, Ctrl+U
  • ความเห็นว่าเทอร์มินัลเป็นหนึ่งในเหตุผลที่ทำให้ Linux มีส่วนแบ่งตลาดต่ำ

    • ประสบการณ์การใช้เทอร์มินัลมีความซับซ้อน
  • การโต้แย้งความเห็นที่ว่า dash shell ไม่รองรับปุ่มลูกศร

    • หากคอมไพล์ด้วย libedit ก็จะรองรับโหมดแก้ไข
    • มาตรฐาน POSIX กำหนดว่าต้องรองรับ "set -o vi"
  • คีย์ไบน์ดิงพื้นฐานของ readline 3 อย่างที่คนรู้ไว้แล้วจะมีประโยชน์

    • Ctrl+W: ลบคำล่าสุด
    • Ctrl+O: รันบรรทัดถัดไปจากประวัติ
    • Ctrl+R: ค้นหาย้อนกลับในประวัติ
  • ความไม่พอใจต่อวิธีการทำงานของ Ctrl-C และ Ctrl-V ใน Windows Terminal

    • แอปเทอร์มินัลบน Linux ไม่ได้ทำงานแบบ Windows Terminal
  • ความเห็นที่ทำให้นึกถึงบทความคลาสสิกของ Linus