ทุกครั้งที่มีคนกำหนดขนาดที่แตกต่างกันสำหรับคอนโซลเสมือนless
ตระหนักถึงความละเอียดของหน้าต่าง (ฉันสมมติว่า ... ); ตามที่มันเปลี่ยนจำนวนบรรทัดของข้อความที่ควรเห็นภาพ พารามิเตอร์นั้นคำนวณอย่างไร?
ทุกครั้งที่มีคนกำหนดขนาดที่แตกต่างกันสำหรับคอนโซลเสมือนless
ตระหนักถึงความละเอียดของหน้าต่าง (ฉันสมมติว่า ... ); ตามที่มันเปลี่ยนจำนวนบรรทัดของข้อความที่ควรเห็นภาพ พารามิเตอร์นั้นคำนวณอย่างไร?
คำตอบ:
หากคุณกำลังมองหาวิธีตรวจสอบจากสคริปต์คุณสามารถทำสิ่งใดสิ่งหนึ่งต่อไปนี้:
tput cols
และtput lines
เป็น manatwork แนะนำแต่ถ้าคุณต้องการรายละเอียดที่นี่เราไป:
สำหรับเทอร์มินัลเสมือน (xterm, et al) มีการioctl()
เรียกระบบที่จะบอกคุณว่าขนาดของหน้าต่างคืออะไร หากทำได้ให้less
ใช้การโทรนี้ นอกจากนี้เมื่อคุณเปลี่ยนขนาดของหน้าต่างสิ่งที่กำลังทำงานอยู่ในหน้าต่างนั้นจะได้รับSIGWINCH
สัญญาณที่แจ้งให้less
ทราบว่าควรตรวจสอบขนาดหน้าต่างใหม่ ตัวอย่างเช่นฉันเริ่มการless
ทำงาน (ตามกระบวนการ ID 16663) เชื่อมต่อกับstrace
และปรับขนาดหน้าต่าง นี่คือสิ่งที่ฉันเห็น:
$ strace -p 16663
Process 16663 attached - interrupt to quit
read(3, 0xbfb1f10f, 1) = ? ERESTARTSYS (To be restarted)
--- SIGWINCH (Window changed) @ 0 (0) ---
rt_sigaction(SIGWINCH, {0x805cf10, [WINCH], SA_RESTART}, {0x805cf10, [WINCH], SA_RESTART}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(1, TIOCGWINSZ, {ws_row=40, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0
ioctl(2, TIOCGWINSZ, {ws_row=40, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0
นี่คือสิ่งที่ต้องทำtput cols
และtput lines
เบื้องหลังถ้าพวกเขาทำได้ สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีนี้ให้ดูman tty-ioctl
และค้นหา TIOCGWINSZ
สำหรับอาคารอื่น ๆ เช่นที่เชื่อมต่อกับพอร์ตอนุกรมไม่มีวิธีรับข้อมูลนี้โดยตรง ในกรณีนี้less
เริ่มมองหาเบาะแสในตัวแปรสภาพแวดล้อม
LINES
และCOLUMNS
มักจะถูกตั้งค่าให้ขนาดเทอร์มินัล ในความเป็นจริงหากbash
หรือzsh
สามารถหาขนาดเทอร์มินัลมันจะตั้งค่าตัวแปรเหล่านี้โดยอัตโนมัติเพื่อให้ง่ายสำหรับโปรแกรมที่ไม่ฉลาดเพื่อดูขนาดเทอร์มินัล อย่างไรก็ตามเชลล์อื่น ๆ ส่วนใหญ่รวมถึงdash
และtcsh
ไม่ได้ตั้งค่าตัวแปรเหล่านี้TERM
มักจะถูกตั้งค่าเป็นประเภทอาคารซึ่งในกรณีนี้ฐานข้อมูล terminfo อาจมีขนาดที่คาดหวังของสถานี หากtput rows
ไม่สามารถใช้ IOCTL (ตัวอย่างเช่นหากคุณเชื่อมต่อผ่านพอร์ตอนุกรม) จะกลับไปใช้ค่าที่บันทึกไว้ที่นี่ สำหรับเทอร์มินัลที่มีขนาดสามารถเปลี่ยนแปลงได้นี่เป็นเพียงการเดาและน่าจะผิดสำหรับข้อมูลเพิ่มเติมให้ดูman tput
ที่คำสั่งเพื่อควบคุมเทอร์มินัลและman terminfo
สำหรับรายการสิ่งต่าง ๆ ที่คุณสามารถบอกให้เทอร์มินัลทำ
หากคุณดูซอร์สโค้ดคุณจะรู้ว่าการless
โทรioctl()
เพื่อดึงขนาดหน้าต่างบน Linux
#ifdef TIOCGWINSZ
{
struct winsize w;
if (ioctl(2, TIOCGWINSZ, &w) == 0)
{
if (w.ws_row > 0)
sys_height = w.ws_row;
if (w.ws_col > 0)
sys_width = w.ws_col;
}
}
#else
#ifdef WIOCGETD
{
struct uwdata w;
if (ioctl(2, WIOCGETD, &w) == 0)
{
if (w.uw_height > 0)
sys_height = w.uw_height / w.uw_vs;
if (w.uw_width > 0)
sys_width = w.uw_width / w.uw_hs;
}
}
#endif
ฉันไม่แน่ใจว่านี่เป็นข้อมูลที่คุณกำลังมองหาหรือไม่ ผมคิดว่าการลงทะเบียนจัดการสัญญาณสำหรับless
SIGWINCH
เมื่อขนาดของเทอร์มินัลเปลี่ยนไปเครื่องจะรับSIGWINCH
สัญญาณและโพรบข้อมูล tty สำหรับมิติปัจจุบันของเทอร์มินัล
http://www.gnu.org/software/libc/manual/html_node/Miscellaneous-Signals.html