ทุกครั้งที่มีคนกำหนดขนาดที่แตกต่างกันสำหรับคอนโซลเสมือน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