มีเหตุผลใดบ้างที่ฉันได้รับ ^ [[เมื่อฉันกดลูกศรขึ้นที่หน้าจอเข้าสู่ระบบของคอนโซล?


32

เมื่อใดก็ตามที่ฉันเข้าสู่ระบบคอนโซลฉันกดupลูกศรโดยเจตนาเพื่อดูคำสั่งที่พิมพ์ไว้ก่อนหน้านี้ ^[[Aแต่ฉันเห็นนี้

แต่เมื่อฉันกดCtrl Alt Print Screen Scroll Lock Pause Break Page Up Page Down Winปุ่มไม่ได้สะท้อนเสียงตัวละครใด ๆ

อะไรคือเหตุผลเบื้องหลัง

การ^[[Aเรียงลำดับของตัวละครมีความหมายอะไรหรือไม่?

ป้อนคำอธิบายรูปภาพที่นี่

คำตอบ:


20

นั่นคือวิธีที่เทอร์มินัลแสดงรหัสคีย์ raw ของคีย์ Up ที่ส่งไปโดยคีย์บอร์ด โดยทั่วไปแล้วเชลล์ของคุณจะสกัดกั้นการกดปุ่ม แต่ไม่มีอะไรที่ต้องทำเมื่อเข้าสู่ระบบ ดังนั้นตัวละครที่คุณพิมพ์จะถูกพิมพ์ไปที่คอนโซลเหมือนกับตัวอักษรอื่น ๆ (หรือตัวเลขหรืออะไรก็ตาม)


3
@RubanSavvy Ctrl, Alt และ Win (มักเรียกว่า Super ใน GNU / Linux world) เป็นตัวดัดแปลง หากคุณกดพวกเขาและปุ่มคุณจะเห็นสิ่งที่พิมพ์บนหน้าจอที่แตกต่างกัน Scroll lock ฉันสงสัยว่าเคอร์เนลจะถูกตีความหรืออย่างอื่นในระดับต่ำสำหรับการควบคุม tty แม้ว่าฉันจะไม่แน่ใจ หน้าขึ้นและลงอาจถูกกลืนโดยgettyหรือloginแม้ว่าฉันไม่แน่ใจว่าทำไม การศึกษาที่คาดเดาได้บอกว่าหน้าจอการพิมพ์ถูกตีความเป็นพิเศษโดยเคอร์เนลด้วยเหตุผลทางประวัติศาสตร์ แม้ว่าฉันจะไม่แน่ใจ 100% ยกเว้นการปรับเปลี่ยน
strugee

3
ควรแก้ไขข้างต้นเป็นคำตอบ
strugee

การสนทนาที่เกี่ยวข้องในการแชท: chat.stackexchange.com/transcript/message/12481097#12481097
strugee

19

คีย์บอร์ดส่งกิจกรรมไปยังคอมพิวเตอร์ เหตุการณ์แจ้งว่า“ สแกนโค้ดไม่ทำงาน” หรือ“ สแกนโค้ดไม่ทำงาน” ที่ปลายอีกด้านหนึ่งของห่วงโซ่การใช้งานที่ทำงานในสถานีคาดหวังว่าการป้อนข้อมูลในรูปแบบของลำดับของตัวละคร (ยกเว้นพวกเขาได้ร้องขอการเข้าถึงแบบ raw เช่นเดียวกับที่เซิร์ฟเวอร์ X ทำ) เมื่อคุณกดAแป้นพิมพ์จะส่งข้อมูล“ รหัสการสแกน 38 ลง” คนขับคอนโซลเงยหน้าขึ้นของรูปแบบแป้นและแปลงนี้ใน“ตัวอักษรa” (หากไม่มีการปรับเปลี่ยนคีย์ถูกกด)

เมื่อคุณกดคีย์หรือคีย์ผสมที่ไม่ส่งผลให้มีตัวอักษรข้อมูลจะต้องถูกเข้ารหัสในรูปแบบของอักขระ ปุ่มบางปุ่มและคีย์ผสมมีอักขระควบคุมที่สอดคล้องกันเช่นCtrl+ Aส่งอักขระ(ค่าไบต์ 1) Returnส่งอักขระ(Ctrl + M, ค่าไบต์ 13) ฯลฯ ปุ่มฟังก์ชันส่วนใหญ่ไม่มีอักขระที่สอดคล้องกันและส่งแทน ลำดับของอักขระที่เริ่มต้นด้วยอักขระ(escape, byte value 27) ตัวอย่างเช่นคีย์Upถูกแปลเป็นลำดับ escape ␛[A(สามตัวอักษร: escape, open bracket, capital A)

พรอมต์ชื่อผู้ใช้บนคอนโซลนั้นเป็นใบ้และไม่เข้าใจลำดับการหลีกเลี่ยงส่วนใหญ่ มันไม่มีคุณสมบัติของรุ่นบรรทัดและประวัติที่คุณคุ้นเคย: สิ่งเหล่านี้มีให้โดยเชลล์และจนกว่าคุณจะเข้าสู่ระบบคุณจะไม่มีเชลล์ ดังนั้นมันจึงแสดงลำดับการหลบหนี มีสัญลักษณ์สำหรับการไม่เป็นตัวละครจึงแสดงเป็น ^[โดยปกติแล้ว^สัญญาณจะถูกใช้เป็นคำนำหน้าสำหรับอักขระควบคุมและการหลบหนีเป็น^[เพราะค่าของไบต์: มันคือค่าไบต์[เป็นลบ 64

หากคุณกดUpที่ shell prompt จะส่งลำดับ 3 ตัวอักษรไปยัง shell ของคุณ เชลล์ตีความสิ่งนี้เป็นลำดับคำสั่ง (โดยทั่วไปเพื่อเรียกคืนรายการประวัติก่อนหน้า) หากคุณกดCtrl+ Vจากนั้นUpที่พร้อมต์เชลล์สิ่งนี้จะแทรกลำดับ escape ที่พร้อมต์: Ctrl+ Vเป็นคำสั่งเพื่อแทรกอักขระถัดไปตามตัวอักษรแทนที่จะตีความมันเป็นคำสั่งดังนั้นอักขระจะไม่ถูกตีความว่าเป็นจุดเริ่มต้นของลำดับหนี .

ปุ่มบางปุ่มเป็นเพียงตัวดัดแปลงและไม่ได้ส่งไปยังแอปพลิเคชันเทอร์มินัล ตัวอย่างเช่นเมื่อคุณกดปุ่มShiftนี้การเข้าพักข้อมูลในโปรแกรมควบคุมขั้วและถูกนำเข้าบัญชีถ้าคุณกดAเพื่อให้คนขับรถส่งไปยังโปรแกรมประยุกต์แทนAa

นอกจากนี้บางปุ่มฟังก์ชั่นอาจไม่ได้รับการแมปในคอนโซลของคุณ

สำหรับมุมมองที่คล้ายกันใน GUI ดูที่เมตาคีย์ของ bash คืออะไร


นี่เป็นคำตอบที่ดีขอบคุณ Gilles เช่นเคย
JoshuaRLi

5

มันไม่เกี่ยวกับวิธีการแสดงคีย์โดย "เทอร์มินัล" (เช่นแอปพลิเคชันเทอร์มินัลอีมูเลเตอร์) สิ่งที่คุณเห็นคือรหัส ANSI ( ลำดับการหลบหนีของ ANSI ) สำหรับการเลื่อนขึ้นหนึ่งบรรทัด แต่แปลเป็นรูปแบบที่พิมพ์ได้

  1. ฮาร์ดแวร์ของคีย์บอร์ดจะส่ง "รหัสสแกน" แต่จะถูกแปลและนำเสนอให้กับแอปพลิเคชันระดับบรรทัดคำสั่งเป็นอักขระ คีย์Aจะกลายเป็นไบต์เดียว: Aหากปุ่ม Shift ไม่ทำงาน (หรือ Shift Lock) aมิฉะนั้น

  2. ในสถานี ANSI สอดคล้องปุ่มลูกศรไม่ส่งตัวเดียว (มีรหัสไม่มีลูกศรในชุดอักขระ ASCII) แต่ 3 ตัวละคร escape-[-A"ลำดับหนี": escape-[-B, C, Dอีกสามปุ่มลูกศรเป็น

  3. ลำดับอักขระเดียวกันจะเลื่อนเคอร์เซอร์ขึ้นหนึ่งบรรทัดหากส่ง (echo'ed) ไปยังเทอร์มินัล ANSI แบบฟิสิคัลเก่า โปรแกรมจำนวนมากรวมถึงเทอร์มินัลอีมูเลเตอร์รับรู้ลำดับตัวอักษรเหล่านี้และทำสิ่งที่เหมาะสม: เทอร์มินัลอีมูเลเตอร์จะย้ายเคอร์เซอร์ขึ้น (นี่คือวิธีที่cursesไลบรารี่ย้ายเคอร์เซอร์ไปรอบ ๆ ) แต่bashจะสกัดกั้นและเลื่อนประวัติแทน

  4. เพื่อหลีกเลี่ยงการวางเคอร์เซอร์จนสุดในสถานที่ในโปรแกรมที่ไม่มีประโยชน์ในการเลื่อนเคอร์เซอร์ไปรอบ ๆ หน้าจอคุณมักจะเห็น ESC ในอินพุตคีย์บอร์ดที่แสดงตามลำดับที่สามารถพิมพ์ได้^[(เนื่องจาก escape สอดคล้องกับcontrol-[) สิ่งนี้ได้รับการจัดการโดยอินเตอร์เฟสอุปกรณ์เทอร์มินัล เห็นstty(1)ไหม ^[[Aเป็นผลให้ลูกศรขึ้นจะแสดงเป็น คุณจะเห็นสิ่งนี้จากบรรทัดคำสั่งหากคุณพิมพ์catกดปุ่มย้อนกลับและกดแป้นลูกศรบางปุ่ม นี่คือสิ่งที่คุณเห็นบนหน้าจอเข้าสู่ระบบคอนโซล

ในที่สุด: Control, Altและปุ่มอื่น ๆ ที่คุณกล่าวถึงจะไม่จับคู่กับลำดับอักขระ มีผลกับอักขระที่ส่งโดยแป้นพิมพ์อื่น (เช่นa/ Aตัวอย่างด้านบน) หรือไม่มีการแมปกับข้อความ การกดแป้นพิมพ์ดังกล่าวสามารถตรวจพบได้โดยโปรแกรมที่ฟังเหตุการณ์แป้นพิมพ์เท่านั้น พวกเขาไม่สามารถมองเห็นได้ด้วยการอ่านจากอินพุตมาตรฐาน (หรือเขียนลงไฟล์)


3

พฤติกรรมนี้แตกต่างจากเปลือกหอย เชลล์ส่วนใหญ่ใช้ไลบรารีที่เรียกว่าreadlineแก้ไขบรรทัดในพร้อมต์ นี่คือการอ้างอิงคำสั่งที่สมบูรณ์สำหรับไลบรารีนี้ดังนั้นเมื่อมีการใช้แอปพลิเคชันreadlineคุณสามารถแก้ไขและนำทางบรรทัดด้วยคำสั่งนี้

ปุ่มลูกศรแนวตั้งถูกกำหนดค่าใน readline เพื่อสำรวจประวัติคำสั่ง และในการเข้าสู่ระบบ promt ไม่มีประวัติคำสั่ง นั่นเป็นเหตุผลที่ตัวละคร^[[Aและ^[[Bพิมพ์บนหน้าจอ ดังนั้น^[[Aหมายความว่าอย่างไร

หน้าคู่มือของ bash กล่าวภายใต้PROMPTING:

\[     begin a sequence of non-printing characters, which could be used to embed
       a terminal control sequence into the prompt

ลำดับหนีสำหรับปุ่มลูกศรใน ANSI คือ:

  • [ValueAเคอร์เซอร์ขึ้น (ซึ่งValueสามารถ emtpy)

  • [ValueBเคอร์เซอร์ลง (ซึ่งValueสามารถ emtpy)


5
คำตอบของคุณเป็นเรื่องเกี่ยวกับสิ่งที่แตกต่างกันเพราะเข้าสู่ระบบให้ถูกพิมพ์และจัดการโดยซึ่งไม่เกี่ยวข้องกับlogin bash
Risto Salminen

1
bashและloginกำลังใช้ไลบรารีเดียวกัน (readline) เพื่อแก้ไขบรรทัด ความแตกต่างก็คือการloginไม่ใช้แป้นลูกศรแนวตั้งเป็นคำสั่งเหมือนbashกัน
ความโกลาหล

ใช่ฉันยอมรับสิ่งนั้น
Risto Salminen

ไวยากรณ์ของ bash นั้นดูเหมือนว่าจะเป็น^[ตัวแทนescapeแต่มันต่างกัน Bash สามารถใช้ไวยากรณ์ใด ๆ ได้เลย ในความเป็นจริงเมื่อคุณเขียน\[Aทุบตีเอาท์พุทสามตัวอักษร: (เช่นการหลบหนี)^[ , [A
alexis

0

เหล่านี้คือANSI รหัสหนี ^[สัญกรณ์ที่เชลล์ของคุณใช้เพื่อแสดงESCไบต์ (ASCII ไบต์ 27) ดังนั้นตัวอย่างของคุณเป็นไบต์ ESC [Aตามด้วยข้อความ อย่างที่คุณเห็นในบทความ Wikipedia ^[[( ESCตามด้วย[) เป็นControl Sequence Introducerหรือ CSI CSI Aหมายถึงเลื่อนเคอร์เซอร์ขึ้นหนึ่งคอลัมน์

หากคุณต้องการดูรหัสหลบหนีในเทอร์มินัลให้พิมพ์ CTRL + V แล้วตามด้วยลำดับคีย์อื่น ยกตัวอย่างเช่น CTRL + V ^[[Aตามด้วยการแสดงที่ลูกศรขึ้น


0

เชลล์คำสั่งตัวอย่างเช่น Bash คือโปรแกรมที่แปลลูกศรขึ้นสู่แอ็คชัน "เรียกคืนคำสั่งก่อนหน้า" คุณไม่มีคำสั่งเชลล์ทำงานอยู่


0

TLDR

คุณอาจกำลังทำงานอยู่shซึ่งส่งออกรหัสดิบที่สร้างขึ้นเมื่อคุณกดปุ่มลูกศรขึ้น

เชลล์ขั้นสูงเช่นbashดักคีย์โค้ดเหล่านี้และทำบางสิ่งกับมัน เช่นแสดงคำสั่งสุดท้ายในประวัติ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.