หน้าต่างคอนโซลซีเรียลที่ปรับขนาดได้หรือไม่


25

เมื่อใช้คอนโซลอนุกรมของระบบของฉันฉันมักจะจบลงด้วยและ$COLUMNS=80$LINES=24

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

screen /dev/mytty baudrateโดยปกติผมเชื่อมต่อไปยังคอนโซลใช้

การเปลี่ยน$TERMตัวแปรสภาพแวดล้อมเป็น "หน้าจอ" หรือ "xterm" ไม่ได้ช่วยอะไร

ฉันจะต้องโทรหาใครgettyบางคนแทนที่จะเป็น vt100 หรือไม่?

จำเป็นต้องพูดว่าทั้งหมดนี้ทำงานได้ดีเมื่อฉันเชื่อมต่อกับเครื่องเดียวกันโดยใช้ ssh

คำตอบ:


26

เช่นเดียวกับผู้แสดงความคิดเห็นก่อนที่ฉันพูดถึงไม่มีทางเลือกที่จะเรียกresizeหลังจากที่ทุกคำสั่งถ้าคุณไม่มีคำสั่งนี้และคุณไม่ต้องการที่จะติดตั้งแพคเกจที่มันอยู่ใน ( xterm) นี่คือ POSIX เชลล์สคริปต์สองตัวที่ทำเหมือนกัน ใช้รหัสหลบหนี terminal ANSI:

res() {

  old=$(stty -g)
  stty raw -echo min 0 time 5

  printf '\0337\033[r\033[999;999H\033[6n\0338' > /dev/tty
  IFS='[;R' read -r _ rows cols _ < /dev/tty

  stty "$old"

  # echo "cols:$cols"
  # echo "rows:$rows"
  stty cols "$cols" rows "$rows"
}

res2() {

  old=$(stty -g)
  stty raw -echo min 0 time 5

  printf '\033[18t' > /dev/tty
  IFS=';t' read -r _ rows cols _ < /dev/tty

  stty "$old"

  # echo "cols:$cols"
  # echo "rows:$rows"
  stty cols "$cols" rows "$rows"
}
  • resจะขึ้นอยู่กับวิธีการแก้ปัญหาที่นำเสนอในhttps://wiki.archlinux.org/index.php/working_with_the_serial_console#Resizing_a_terminal มันทำงานได้ดังต่อไปนี้:

    1. ตำแหน่งเคอร์เซอร์ถูกบันทึกไว้ ( \0337, DECSC)
    2. เคอร์เซอร์ถูกย้ายไปที่จุดล่างขวาสุดที่เป็นไปได้ ( \033[r\033[999;999H, DECSTBM? + CUP)
    3. มีการรายงานตำแหน่งเคอร์เซอร์ ( \033[6n, DSR)
    4. เคอร์เซอร์จะถูกย้ายกลับไปยังตำแหน่งที่บันทึกไว้ก่อนหน้า ( \0338, DECRC)
  • res2ได้รับอิทธิพลresize.shจาก xterm (ดูhttps://github.com/ThomasDickey/xterm-snapshots/blob/master/vttests/resize.sh ) มันใช้xtermรหัสเฉพาะสำหรับการรับข้อมูลที่เราต้องการ (ดำเนินการในหลาย terminal emulators) ดู: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Functions-using-CSI-_-ordered -by-the-final-character_s_ ( "รายงานขนาดของพื้นที่ข้อความเป็นตัวอักษร" )

BTW ใน.profileไฟล์ของฉันคุณจะพบสิ่งต่อไปนี้: [ $(tty) = /dev/ttyS0 ] && res เพื่อให้ขนาดเทอร์มินัลถูกกำหนดในทุกการล็อกอินผ่านสายอนุกรม (ขนาดที่ฉันใช้สำหรับการจัดการ) เช่นหลังจากคุณรีบูทอุปกรณ์
ดูความคิดโดยrsawในความคิดเห็นเพื่อให้มีบรรทัด[ $(tty) = /dev/ttyS0 ] && trap res2 DEBUGแทนดังนั้นการปรับขนาดจะทำงานหลังจากทุกคำสั่ง (โปรดทราบว่า AFAIK ไม่ใช่หรือไม่สามารถทำได้ทุกครั้งbusybox)


3
PS: หากต้องการทำให้ถาวรมากขึ้นให้เพิ่ม[[ $(tty) == /dev/ttyS0 ]] && trap res2 DEBUGหนึ่งในโปรไฟล์การกำหนดค่าเชลล์ (เช่น/etc/profile,, ~/.bash_profile) สิ่งนี้จะทำให้มันรันหลังจากทุกคำสั่งเดียว (ซึ่งจะเป็นสิ่งที่ดีถ้าคุณกำลังปรับขนาดหน้าต่าง / บานหน้าต่างด้วย screen / tmux / terminal-emulator)
rsaw

2
หลังจากใช้งานไปสองสามนาทีฉันก็รู้ได้อย่างรวดเร็วว่าทั้งres& & res2ช้าเกินไปสำหรับทุกอย่างยกเว้นใช้ในการลงชื่อเข้าใช้ครั้งแรก บนเครื่องของฉันพวกเขาทั้งสองใช้เวลา 0.5 วินาทีในการเสร็จสิ้น ... ทำให้คำสั่งทั้งหมดของฉันดูเชื่องช้า (เมื่อใช้กับดัก DEBUG) อ๊ะ! ไม่สามารถมีได้ xtermคิดว่าผมจะได้รับการติดตั้ง
rsaw

3
@phk xterm resizeเป็น waaaay เร็วขึ้น - ปกติ 0.002 วินาที
rsaw

1
@rsaw โอ้ตกลงดีรู้ฉันคิดว่ามันจะทำงานคล้ายกันและดังนั้นจึงช้าเหมือนกัน ฉันจำได้ว่าหนึ่งในบางคนbusyboxดูเหมือนจะช้าสำหรับฉัน
phk

1
ขอบคุณสำหรับโซลูชันแบบสแตนด์อโลนนี้ ฉันใช้ distro คอนโซลเท่านั้นที่ไม่มี x11 หรือ xterm ติดตั้งดังนั้นจึงresizeไม่ใช่ตัวเลือก
thom_nic

16

เพียงเพื่อบันทึกนี่คือคำตอบสำหรับปัญหานี้ (Usenet ชนะ):

การประยุกต์ใช้คอนโซลการทำงานภายในโปรแกรมประยุกต์เสมือนขั้ว ( xterm, rxvtและเพื่อน ๆ ) จะได้รับSIGWINCHหลังจากการดำเนินการปรับขนาดได้ที่สถานที่ ดังนั้นแอปพลิเคชันจะสามารถวาดหน้าต่าง ฯลฯ ในตัวจัดการสัญญาณที่เกี่ยวข้อง

น่าเสียดายที่ใช้คอนโซลอนุกรมไม่มีกลไกดังกล่าว

อย่างไรก็ตามเป็นไปได้ที่แอปพลิเคชันจะขอขนาดหน้าต่างคอนโซลปัจจุบันอย่างแข็งขัน ดังนั้นสิ่งที่ดีที่สุดที่สองคือการทำเช่นนี้ทุกครั้งที่พิมพ์พรอมต์คำสั่งโดยเชลล์

สิ่งนี้สามารถเกิดขึ้นได้โดยการคอมไพล์ไฟล์ที่ปรับขนาดได้พิเศษก่อนแล้วจึงใช้สิ่งต่อไปนี้ในbashrc:

if [ $(tty) == '/dev/ttyS0' ]; then
  trap resize DEBUG
fi

แน่นอนว่าสิ่งนี้จะไม่เปลี่ยนการตั้งค่าขนาดคอนโซลในแอปพลิเคชันคอนโซลในขณะใช้งานจริง


1
ไม่ควรที่จะเป็นไปได้ที่จะเรียกใช้โปรโตคอลเหนือเส้นอนุกรมที่ไม่นำเสนอคุณลักษณะทั้งหมดหรือไม่ ฉันหมายความว่าเรามีลูกค้าและเซิร์ฟเวอร์ พวกเขาสามารถใช้ลำดับการหลบหลีกแบบอินแบนด์เพื่อทำทุกอย่างเกี่ยวกับและยังคงทำงานกับคอนโซลข้อความธรรมดาได้!
Evi1M4chine

1
จริงๆแล้วความคิดเห็นในรหัสทำให้ธรรมดาว่าไม่ใช่รุ่นresizeที่ติดตั้งในระบบของคุณ
Thomas Dickey

9

เทอร์มินัล "ปรับขนาดได้" เช่นนี้เป็นผลมาจาก NAWS ( Negotiate About Window Sizeจากตัวเลือกขนาดหน้าต่าง Telnet RFC 1073 )

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

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

เมื่อคอมพิวเตอร์ไม่รู้จักขนาดหน้าจอมันมักจะตั้งขนาดที่แสดงโดยstty -a(แถวและคอลัมน์) เป็นศูนย์ สำหรับการใช้งานแบบโต้ตอบนี่เป็นสิ่งที่ไม่เป็นมิตรและบางระบบใช้ตัวแปรสภาพแวดล้อมLINESและCOLUMNSช่วยเหลือ ค่าที่กำหนดอาจได้รับมาจากคำอธิบายขั้ว; บ่อยครั้งที่พวกเขาจะ hardcoded เพียง แบบแผนสำหรับตัวแปรเหล่านี้ต้องการให้มีผลบังคับใช้เว้นแต่จะถูกระงับไว้อย่างชัดเจนเช่นในuse_envฟังก์ชั่นการใช้งานคำสาป ในด้านบวกตัวแปรเหล่านั้นมีประโยชน์เมื่อไม่มีข้อมูลที่เชื่อถือได้ ด้านลบไม่มีวิธีที่สะดวกในการแก้ไขตัวแปรเหล่านั้น

resizeโปรแกรม (ยูทิลิตี้ให้กับxterm) สามารถใช้ VT100 สไตล์รายงานตำแหน่งของเคอร์เซอร์ลำดับหนีสำหรับการกำหนดขนาดของหน้าจอ สิ่งนี้สามารถเรียกใช้ได้จากบรรทัดคำสั่ง ไม่มี (อีกครั้ง) ไม่มีวิธีที่สะดวกในการทำโดยอัตโนมัติ ในฐานะที่เป็นผลข้างเคียง, resizeการปรับปรุงข้อมูลในแถว / sttyคอลัมน์มองเห็นได้ด้วย มันใช้สำหรับการให้ตัวแปรสภาพแวดล้อมการปรับปรุงส่วนใหญ่มีประโยชน์สำหรับกรณีเช่นนี้ที่ไหนLINESและCOLUMNS มีการตั้งค่าและควรได้รับการปรับปรุง


3

นี่เป็นอีกวิธีการหนึ่งที่ใช้งานได้ดีเยี่ยมสำหรับฉันบนระบบ Linux ที่ฝังอยู่ (Overo running Angstrom) ฉันเพิ่งเรียกใช้จากไฟล์. bashrc ของฉัน ฉันไม่ต้องการใช้การปรับขนาดเพราะต้องติดตั้งแพ็คเกจ X และฉันไม่ต้องการมัน

การบอก Raspberry Pi ว่าเทอร์มินัลของคุณมีขนาดใหญ่กว่า 24 บรรทัด | บล็อกความคิดตื้น ๆ


3
กรุณาอย่าเพียงแค่โพสต์ลิงค์: รวมถึงรายละเอียดที่เกี่ยวข้องเพื่อให้ข้อมูลที่สามารถใช้ได้ที่นี่เช่นกัน ...
jasonwryan

1
น่าเสียดายที่มันต้องการ Python
Craig McQueen


1

เมื่อเรียกใช้เซสชั่นเชลล์บนสายอนุกรมก็เพียงพอที่จะเรียกresizeคำสั่งภายในเซสชันนั้น - หลังจากสร้างการเชื่อมต่อและหลังจากการเปลี่ยนแปลงรูปทรงเรขาคณิตของเทอร์มินัลแต่ละครั้ง

resizeคำสั่งเป็นส่วนหนึ่งของ xterm แต่ไม่ได้ขึ้นอยู่กับ X11 ตัวอย่างเช่นใน Fedora xterm-resizeก็บรรจุแยกเป็น

วิธีการทำงาน: คำสั่งปรับขนาดวัดความสูง / ความกว้างผ่านการเคลื่อนไหวของเคอร์เซอร์แล้วส่งค่าเหล่านั้นไปยังเทอร์มินัลด้วยลำดับการหลีกเลี่ยง

ด้วยเชลล์อย่าง zsh สิ่งนี้ยังทำการอัพเดตLINESและCOLUMNSตัวแปรโดยอัตโนมัติ (อีกทางหนึ่งสามารถประเมินข้อความสั่งการส่งออกที่คำสั่งพิมพ์ไปยัง stdout)

เหตุใดจึงมีความจำเป็น: ด้วยเซสชันโลคัลหรือ ssh เทอร์มินัลสามารถส่งสัญญาณเซสชันเกี่ยวกับการเปลี่ยนแปลงทางเรขาคณิต (cf. SIGWINCH) กลไกนี้ไม่ทำงานผ่านการเชื่อมต่อแบบอนุกรม


0

นี่คือฟังก์ชั่นปรับขนาดที่ง่ายและรวดเร็วที่ใช้งานได้เฉพาะกับการทุบตีเท่านั้น มันถูกดัดแปลงจาก resk ของ phk ทำให้ใช้ bash's read -d delimเพื่อหลีกเลี่ยงการปล่อยให้เวลาหมดเพื่ออ่านให้จบ

resize() {
  old=$(stty -g)
  stty -echo
  printf '\033[18t'
  IFS=';' read -d t _ rows cols _
  stty "$old"
  stty cols "$cols" rows "$rows"
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.