บังคับให้ telnet / ssh ใช้ crtl-H สำหรับ backspace


9

ฉันมีอุปกรณ์บางอย่างเชื่อมต่อกับเซิร์ฟเวอร์คำศัพท์อนุกรมของ Cisco; ทำงานได้ดีมากเมื่อฉันtelnetโดยตรงไปยังพอร์ตใน Cisco อย่างไรก็ตามฉันมีอุปกรณ์ที่ดื้อรั้นไม่กี่ตัวที่จะไม่ใช้Backspaceเนื่องจากถูกแมปใน telnet โดยค่าเริ่มต้น

ในกรณีที่มีความสำคัญฉัน telnet จากrxvtภายใต้ Debian squeeze (ใน X Window) TERMถูกตั้งค่าให้rxvtแต่มันไม่สำคัญว่าผมใช้vt100, vt101หรือxterm... การเปลี่ยนแปลงTERMจะไม่มีผล ผมเริ่มลงที่ถนนของการเปลี่ยนแปลงTERMขึ้นอยู่กับสิ่งที่ฉันเห็นในเก่ามิตคำถามที่พบบ่อย FWIW stty erase ^hและstty erase ^?ไม่ทำงานเช่นกัน

ฉันสังเกตเห็นว่าBackspaceอุปกรณ์เหล่านี้ทำงานอย่างถูกต้องหากฉันใช้ซ็อกเก็ต TCP แบบดิบจากnetcat... เช่นnc 192.168.12.117 2006; อย่างไรก็ตามจากนั้นฉันพบปัญหาอื่น ๆ เกี่ยวกับรหัสผ่านที่ไม่ซ่อนหรือการสลับหน้าจอเทอร์มินัล

ฉันจะเลือกบังคับ telnet และ ssh เพื่อแม็พBackspaceกับCtrlHอุปกรณ์เหล่านี้ได้อย่างไร? นอกจากนี้ฉันควรใช้เกณฑ์ใดในการประเมินว่านี่เป็นข้อบกพร่องในอุปกรณ์หรือไม่

แก้ไข

ในกรณีที่มันเป็นเรื่องสำคัญนี้เป็นผลผลิตจากshowkey -aคีย์ในคำถาม ... ^?สอดคล้องกับการBackspaceและเป็น^H CtrlHดูเหมือนว่าฉันควรจะเข้าใกล้เมื่อฉันดูThe Linux Keyboard และ Console Howtoแต่ฉันไม่สามารถถอดรหัสสิ่งที่ฉันสามารถทำได้เพื่อเปลี่ยนสิ่งนี้ ฉันได้ลองใช้คาถาต่างๆโดยloadkeysไม่มีผลกระทบ

[mpenning@hotcoffee docs]$ sudo showkey -a

Press any keys - Ctrl-D will terminate this program

^?      127 0177 0x7f
^H        8 0010 0x08

ฉันยังรวมเอาท์พุทที่เกี่ยวข้องมาdumpkeysด้วยเช่นกัน ... นี่คือการแมปปัจจุบันในระบบของฉัน (ซึ่งไม่สามารถใช้ได้กับอุปกรณ์บางอย่างที่สงสัย) ถ้าฉันสามารถหาวิธีที่Backspaceจะทำสิ่งเดียวกันCtrlHฉันจะมีทางออก

[mpenning@hotcoffee docs]$ sudo dumpkeys | grep -Ei "backspace|127"
keycode   8 = BackSpace        ampersand        braceleft       
keycode  14 = BackSpace        Delete          
        control keycode  14 = BackSpace       
keycode 127 =
[mpenning@hotcoffee docs]$

1
คุณเคยลองssty erase '^?'ไหม หากอุปกรณ์ยืนยันใน a C-hนั่นไม่ใช่การโทรของ telnet นั่นคือเทอร์มินัล (อีมูเลเตอร์)
Gilles 'หยุดความชั่วร้าย'

@Gilles ความคิดเห็นของคุณไม่ถูกต้องโปรดดูคำตอบของฉันด้านล่าง
Mike Pennington

คำตอบ:


10

ในที่สุดผมก็พบคำตอบในแอนน์ Baretta ของลินุกซ์คีย์บอร์ดหออัปยศ ... มันดูเหมือนว่าการเปลี่ยนแปลงที่สำคัญในการแมปxterm/rxvttelnetไม่ดีสำหรับ

ฉันตรวจสอบสิ่งนี้เมื่อฉันดมการเชื่อมต่อ telnet ครั้งแรกที่ฉันดมเซสชั่น telnet และเห็นว่าBackspaceส่งไป0x7fยังโฮสต์ ต่อไปฉันจงใจยากจนBackspaceในrxvtการใช้stty erase $(เช่นการทำแผนที่ Backspace ของฉันไปที่เครื่องหมายดอลลาร์ในrxvt) หลังจากทำสิ่งนี้ฉันต้องกด$แบ็คสเปrxvtซ แต่telnetก็ยังส่ง0x7fเมื่อฉันใช้Backspaceกับโฮสต์ระยะไกล

สารละลาย

สร้างสคริปต์ที่เรียกว่าkbdfix(ด้านล่าง) และทำให้สามารถเรียกใช้ด้วย755สิทธิ์ คุณจะต้องโหลดtclshและexpectแพ็กเกจจากคลังการแจกจ่ายของคุณ

#!/usr/bin/expect

#Name this file as kbdfix and make it executable in your path
eval spawn -noecho $argv

interact {
 \177        {send "\010"}
 "\033\[3~"  {send "\177"}
}

ตอนนี้เพื่อเชื่อมต่อกับโฮสต์ที่ใช้งานไม่ได้ฉันพิมพ์kbdfix telnet 192.168.12.117 2006และใช้Backspaceงานได้

หมายเหตุสำหรับทุกคนที่สับสนภายในปี 2549 ข้างต้น ... นั่นคือพอร์ต TCP ที่เซิร์ฟเวอร์คำของ Cisco ใช้สำหรับการเชื่อมต่อแบบอนุกรมกับคอนโซลของอุปกรณ์ที่ใช้งานไม่ได้ (ในกรณีนี้คือสวิตช์ Brocade FCX)

หากคุณเป็นเพียงเน็ตไปยังอุปกรณ์ที่ไม่ชอบคุณจะใช้Backspace kbdfix telnet <addr_of_the_broken_device>ฉันยังใช้สิ่งนี้กับ ssh เมื่อฉันไปยังสวิตช์อีเธอร์เน็ต DLink DGS-3200 ที่มีปัญหาคล้ายกัน kbdfix ssh 172.16.1.26ไวยากรณ์คือ


2
stty erase $ไม่ได้จับคู่คีย์ "backspace" กับ "$" แต่จะแจ้งให้ไดรเวอร์ tty ทราบว่าในการที่จะลบอักขระจำเป็นต้องใช้คีย์ "$" เมื่อคุณรัน telnet คุณจะอยู่ในโหมด raw ดังนั้นการตั้งค่านี้จะถูกละเว้น วิธีแก้ปัญหาอย่างง่ายคือการกำหนดค่าเทอร์มินัลอีมูเลเตอร์ของคุณให้ส่ง ^ H สำหรับแบ็คสเปซตามที่ตั้งใจไว้อีกวิธีหนึ่งคือการใช้แฮ็คของคุณซึ่งแปลอักขระเหล่านี้ได้ทันที
jlliagre

@jlliagre ใช่ฉันค้นพบวิธีsttyไม่เปลี่ยนแปลงtelnet's แป้นพิมพ์อ่านเมื่อฉันใช้wireshark; อย่างไรก็ตามความจริงสำคัญนี้ไม่ชัดเจนสำหรับฉันจนกว่าฉันจะดมกลิ่น ฉันจะตรวจสอบว่าฉันสามารถเปลี่ยน Backspace ให้ใช้Control_hในrxvt... หรือฉันอาจต้องคิดหาคำอื่น
Mike Pennington

@ ไมค์: ฉันคิดว่าคุณยังสับสนเกี่ยวกับบางสิ่งบางอย่าง (ซึ่งฉันยอมรับว่าไม่ใช่ jlliagre หรือพูดถึงอย่างชัดเจนฉันได้อัปเดตคำตอบของฉัน) sttyจำเป็นต้องเรียกใช้ในด้านแอปพลิเคชัน ผมขอข้อสงสัยtelnetถูกแปลป้อนอักขระหรือที่คุณจำเป็นต้องใช้script; เพียงทำงานsttyบนเครื่องระยะไกลอาจจะทำเคล็ดลับ
Gilles 'หยุดความชั่วร้าย' ใน

@Gilles, sttyเครื่องระยะไกลเป็นอุปกรณ์เครือข่ายมันไม่ได้มี
Mike Pennington

1
@Mike: เมื่อคุณใช้ netcat เทอร์มินัลของคุณอยู่ในโหมดสุก: คุณเขียนบรรทัดแก้ไขภายในเครื่องและEnterส่ง เมื่อคุณใช้ telnet เทอร์มินัลของคุณจะอยู่ในโหมด raw: อักขระแต่ละตัวจะถูกส่งไปยังแอปพลิเคชันทันที ดูเช่นจุดเริ่มต้นของหน้านี้หรือบทความวิกิพีเดียนี้
Gilles 'SO- หยุดความชั่วร้าย'

3

Backspace และ Control-H ได้รับการออกแบบให้เหมือนกัน แต่ทุกวันนี้โดยเฉพาะอย่างยิ่งบน Linux คุณมักจะมี backspace ที่ส่งการลบและลบที่ส่งลำดับ escape แปลก ๆ

ไม่ว่าในกรณีใดและเท่าที่ฉันทราบตัวแปร telnet หรือ TERM ไม่ควรเปลี่ยนสิ่งที่แบ็คสเปซส่งนี่เป็นคุณสมบัติการกำหนดค่าเทอร์มินัลอีมูเลเตอร์


คำถามของคุณอยู่บนสมมติฐานของ telnet กำลังทำการประมวลผลเฉพาะของคีย์ backspace ซึ่งฉันเชื่อว่าผิด ฉันควรจะใส่มันเป็นความคิดเห็นแทนคำตอบแน่นอน
jlliagre

AFAICT telnetไม่สนใจการแมปเทอร์มินัลท้องถิ่นของแป้นพิมพ์ บันทึกของ Anne Barreta เกี่ยวกับแป้นพิมพ์และ telnet
Mike Pennington

ฉันกลัวว่าคุณเข้าใจผิดว่า stty ทำอะไร
jlliagre

3

โปรแกรมควรสอบถามการตั้งค่าเทอร์มินัลเพื่อค้นหาว่าอักขระแบ็คสเปซคืออะไร ( ^hและ^?คือ\010และ\177มีสองตัวเลือกอยู่ตรงนั้น) ใช้stty erase '^h'หรือstty erase '^?'เพื่อประกาศสิ่งที่เทอร์มินัลของคุณส่ง

หากคุณเข้าสู่ระบบจากระยะไกล (กับ Telnet, rsh หรือ SSH) ภายในอาคารผู้โดยสารทราบว่าคุณจะต้องทำงานในด้านการประยุกต์ใช้stty sttyไม่ได้บอกให้เทอร์มินัลทำอะไรที่แตกต่าง แต่แจ้งให้ทราบถึงไดรเวอร์เทอร์มินัลท้องถิ่น (เช่นส่วนที่เชื่อมต่อกับแอพพลิเคชั่นที่รันในเทอร์มินัล) เกี่ยวกับเทอร์มินัล ในทำนองเดียวกันถ้าคุณเรียกใช้ Screen หรือซอฟต์แวร์ terminal-in-terminal ที่คล้ายกันคุณจะต้องเรียกใช้sttyในหน้าต่างหน้าจอแต่ละหน้าต่าง (แต่โดยปกติแล้วหน้าจอสามารถกำหนดค่าให้ทำสิ่งที่ถูกต้องจากไฟล์กำหนดค่าหากไม่ได้ผล )

ความแตกต่างของพฤติกรรมที่คุณสังเกตเห็นจากnetcatvs. telnetเกิดจากวิธีการใช้เทอร์มินัล: * ใน netcat เทอร์มินัลอยู่ในโหมดทีละบรรทัด (เรียกอีกอย่างว่า "โหมดปรุงสุก") คุณแก้ไขบรรทัด (โดยใช้คุณลักษณะเอดิชันในตัวของเทอร์มินัลโลคัลและอื่น ๆ โดยเฉพาะการตั้งค่า stty ในเครื่อง) จากนั้นส่งในสถานะสุดท้ายไปยังโฮสต์ระยะไกล * ใน telnet เทอร์มินัล (ภายในเครื่อง) อยู่ในโหมดตัวอักษรต่ออักขระ (หรือที่เรียกว่า“ โหมดดิบ”) การกดแป้นทุกครั้งจะไปที่ telnet โดยตรงซึ่งจะส่งไปยังระบบรีโมตทันที คุณขึ้นอยู่กับคุณสมบัติของรุ่นระบบของรีโมต

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

ด้วย xterm เป็นเรื่องง่าย: มีการตั้งค่าเพื่อสลับอักขระที่ส่งมาจากBackSpaceปุ่มขณะใช้งาน จากเมนูปุ่มซ้ายสลับ "Delete is DEL" โปรแกรมให้ส่งลำดับหนี \e[?67hจะมีการBackSpaceส่ง^hหรือ\e[?67lที่จะมีการส่งBackSpace ทรัพยากรที่สอดคล้องกันคือ^? XTerm.backarrowKeyIsEraseเทอร์มินัลอีมูเลเตอร์อื่น ๆ อาจมีหรือไม่มีคุณสมบัติอินเตอร์เฟสที่เหมือนกันหรือรองรับลำดับการหลบหนี

การเลียนแบบขั้วหลายคนส่งหนึ่ง^hหรือ^?เมื่อคุณกดBackSpaceและตัวละครอื่น ๆ เมื่อคุณกด+Ctrl BackSpaceสิ่งนี้มีประโยชน์ในการเหน็บแนม

โปรดทราบว่าshowkeysและเพื่อนมีความเกี่ยวข้องเฉพาะในคอนโซล Linux ไม่ใช่ภายใน X

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