Làm thế nào ít biết độ phân giải thiết bị đầu cuối?


12

Mỗi khi ai đó đặt kích thước khác nhau cho bảng điều khiển ảo, sẽ lessnhận ra độ phân giải cửa sổ (tôi giả sử rằng ...); theo đó, nó thay đổi bao nhiêu dòng văn bản mà nó nên hình dung. Làm thế nào là tham số được tính toán?


Uhm ... ok, nhưng tôi có thể tìm thấy thủ tục đó được thực hiện ở đâu?
Giuseppe Crinò

Câu trả lời:


22

Nếu bạn đang tìm cách kiểm tra từ một tập lệnh, bạn có thể thực hiện một trong những cách sau:

  • Chạy tput colstput lines, như manatwork gợi ý
  • kiểm tra các giá trị của $ LINES và $ COLUMNS

Nhưng nếu bạn muốn biết chi tiết, ở đây chúng tôi đi:

Đối với các thiết bị đầu cuối ảo (xterm, et al), có một ioctl()cuộc gọi hệ thống sẽ cho bạn biết kích thước của cửa sổ. Nếu có thể, hãy lesssử dụng cuộc gọi này. Hơn nữa, khi bạn thay đổi kích thước của cửa sổ, bất cứ thứ gì đang chạy trong cửa sổ đó đều nhận được SIGWINCHtín hiệu cho lessbiết rằng nó sẽ kiểm tra kích thước cửa sổ mới. Chẳng hạn, tôi bắt đầu lesschạy (như ID tiến trình 16663), kết nối với nó stracevà thay đổi kích thước cửa sổ. Đây là những gì tôi thấy:

$ 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

Đây cũng là những gì tput colstput lineslàm đằng sau hậu trường, nếu họ có thể. Để biết thêm thông tin về phương pháp này, hãy xem man tty-ioctlvà tìm kiếm TIOCGWINSZ.

Tuy nhiên, đối với các thiết bị đầu cuối khác như các cổng được kết nối với cổng nối tiếp, không có cách nào để nhận thông tin này trực tiếp. Trong trường hợp đó, lessbắt đầu tìm kiếm manh mối trong các biến môi trường.

  • LINESCOLUMNSthường sẽ được đặt thành kích thước thiết bị đầu cuối. Trong thực tế, nếu bashhoặc zshcó thể tìm thấy kích thước thiết bị đầu cuối, nó sẽ tự động thiết lập các biến này, để giúp các chương trình không thông minh dễ dàng nhìn thấy kích thước thiết bị đầu cuối. Tuy nhiên, hầu hết các shell khác, bao gồm dashtcsh, không đặt các biến này.
  • TERMthường được đặt thành loại thiết bị đầu cuối, trong trường hợp đó, cơ sở dữ liệu terminfo có thể chứa kích thước dự kiến ​​của thiết bị đầu cuối. Nếu tput rowskhông thể sử dụng IOCTL (ví dụ: nếu bạn được kết nối qua cổng nối tiếp), nó sẽ quay trở lại các giá trị được ghi ở đây. Đối với một thiết bị đầu cuối có kích thước có thể thay đổi, đây chỉ là dự đoán và có khả năng sai.

Để biết thêm thông tin, hãy xem man tputlệnh để điều khiển thiết bị đầu cuối và man terminfođể biết danh sách những điều bạn có thể yêu cầu thiết bị đầu cuối thực hiện.


Cơ sở dữ liệu terminfo không làm những gì được chỉ ra ở đây. Câu trả lời của @ warl0ck, chứa ít thông tin hơn, chính xác hơn.
Thomas Dickey

@ThomasDickey Bạn nói đúng; tất cả những gì nó có là giá trị mong đợi. Sửa câu trả lời của tôi; cảm ơn.
Jander

7

Nếu bạn xem mã nguồn, bạn sẽ biết lesscác cuộc gọi ioctl()để lấy kích thước cửa sổ trên 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

1

Tôi không chắc chắn nếu đây là thông tin mà bạn đang tìm kiếm. Tôi đoán lessđăng ký một xử lý tín hiệu cho SIGWINCH. Khi kích thước của thiết bị đầu cuối thay đổi, nó nhận được SIGWINCHtín hiệu và thăm dò thông tin tty cho kích thước hiện tại của thiết bị đầu cuối. http://www.gnu.org/software/libc/manual/html_node/Misiverse-Signals.html

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.