cửa sổ bàn điều khiển nối tiếp thay đổi kích thước?


25

Khi sử dụng bàn điều khiển nối tiếp của hệ thống của tôi, tôi luôn luôn kết thúc với $COLUMNS=80$LINES=24.

Mặc dù tôi có thể thay đổi các biến này theo cách thủ công, nhưng điều này hơi khó chịu khi thực hiện điều này bất cứ khi nào cửa sổ thiết bị đầu cuối phía máy khách đã được thay đổi kích thước.

Thông thường tôi đang kết nối với bàn điều khiển bằng cách sử dụng screen /dev/mytty baudrate.

Thay đổi $TERMbiến môi trường thành "màn hình" hoặc "xterm" không giúp ích gì.

Tôi có cần gọi gettyvới một số người thay vì vt100 không?

Không cần phải nói rằng tất cả những thứ này hoạt động tốt, khi tôi kết nối với cùng một máy bằng ssh.

Câu trả lời:


26

Giống như các nhà bình luận trước tôi đã đề cập, không có cách nào khác để gọi resizesau mỗi lệnh, nếu bạn không có lệnh này và bạn không muốn cài đặt gói trong đó ( xterm), đây là hai tập lệnh shell POSIX làm tương tự sử dụng mã thoát thiết bị đầu cuối 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"
}

BTW, trong .profiletệp của tôi, bạn sẽ tìm thấy như sau: [ $(tty) = /dev/ttyS0 ] && res để kích thước thiết bị đầu cuối được xác định trên mỗi lần đăng nhập qua dòng nối tiếp (cái tôi sử dụng để quản lý), ví dụ sau khi bạn khởi động lại thiết bị. Thay vào đó, hãy
xem ý tưởng của rsaw trong các bình luận để có dòng [ $(tty) = /dev/ttyS0 ] && trap res2 DEBUGở đó để thay đổi kích thước chạy sau mỗi lệnh (lưu ý rằng AFAIK không phải lúc nào cũng không thể thực hiện được busybox).


3
PS: Để làm cho lâu dài hơn, hãy thêm [[ $(tty) == /dev/ttyS0 ]] && trap res2 DEBUGvào một trong các cấu hình cấu hình shell (ví dụ /etc/profile,, ~/.bash_profile). Điều này sẽ làm cho nó được chạy sau mỗi lệnh đơn (điều này sẽ chỉ là một điều tốt nếu bạn thay đổi kích thước cửa sổ / cửa sổ bằng màn hình / tmux / terminal-giả lập).
rsaw

2
Sau khi sử dụng một vài phút, tôi nhanh chóng nhận ra rằng cả hai res& res2quá chậm cho bất cứ thứ gì ngoại trừ sử dụng trong lần đăng nhập đầu tiên. Trên các máy của tôi, cả hai đều mất 0,5 giây để hoàn thành ... làm cho tất cả các lệnh của tôi trở nên chậm chạp (khi được sử dụng với bẫy DEBUG). Rất tiếc! Không thể có điều đó. Đoán tôi sẽ được cài đặt xterm.
rsaw

3
@phk xterm resizelà waaaay nhanh hơn - thường là 0,002 giây.
rsaw

1
@rsaw Oh OK, tốt để biết, tôi nghĩ rằng nó sẽ hành xử tương tự và do đó chậm tương tự. Tôi nhớ rằng một trong những busyboxes dường như chỉ chậm với tôi.
phk

1
Cảm ơn giải pháp độc lập này. Tôi đang sử dụng một bản phân phối chỉ dành cho bảng điều khiển không được cài đặt x11 hoặc xterm nên resizekhông phải là một tùy chọn.
thom_nic

16

Chỉ cần cho hồ sơ, đây là câu trả lời cho vấn đề này (Usenet đã thắng):

Giao diện điều khiển ứng dụng chạy bên trong ứng dụng thiết bị đầu cuối ảo ( xterm, rxvtvà bạn bè) sẽ nhận được SIGWINCHsau khi một hoạt động thay đổi kích thước đã diễn ra. Do đó, ứng dụng sẽ có thể vẽ lại cửa sổ, vv trong trình xử lý tín hiệu tương ứng.

Thật không may khi sử dụng một giao diện điều khiển nối tiếp, không có cơ chế như vậy.

Tuy nhiên, ứng dụng có thể chủ động yêu cầu kích thước cửa sổ giao diện điều khiển hiện tại . Vì vậy, điều tốt nhất thứ hai là làm điều này mỗi khi dấu nhắc lệnh được in bởi trình bao.

Điều này có thể đạt được bằng cách trước tiên biên dịch một kích thước đặc biệt thay đổi thực thi và sau đó sử dụng như sau trong bashrc:

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

Tất nhiên, điều này sẽ không thay đổi cài đặt kích thước bàn điều khiển trong ứng dụng bàn điều khiển trong thời gian chạy.


1
Không nên chạy giao thức qua dòng nối tiếp, cung cấp tất cả các tính năng không? Ý tôi là chúng ta có một khách hàng và một máy chủ. Họ có thể sử dụng các chuỗi thoát trong băng thông để làm mọi thứ và vẫn hoạt động với bảng điều khiển nối tiếp văn bản đơn giản!
Evi1M4chine

1
Trên thực tế, nhận xét trong mã làm cho nó rõ ràng rằng đó không phải là phiên bản resizeđược cài đặt trên hệ thống của bạn.
Thomas Dickey

9

Các thiết bị đầu cuối "có thể thay đổi kích thước" như vậy là kết quả của NAWS ( Negotiate About Window Sizetừ Tùy chọn Kích thước Cửa sổ Telnet của RFC 1073 ).

Nếu bạn được kết nối trực tiếp với máy tính bằng cổng nối tiếp, sẽ không có sự thương lượng nào liên quan và máy tính không có kiến ​​thức trực tiếp về kích thước màn hình của thiết bị đầu cuối của bạn.

Nếu một thiết bị đầu cuối có thể thương lượng kích thước, máy tính sẽ gửi SIGWINCHđến các ứng dụng đang chạy trong thiết bị đầu cuối, bảo họ cập nhật khái niệm về kích thước màn hình.

Khi máy tính không biết kích thước màn hình, nó thường đặt kích thước được hiển thị bởi stty -a(hàng và cột) thành không. Để sử dụng tương tác, đây là một chút không thân thiện, và một số hệ thống sử dụng các biến môi trường LINESCOLUMNSđể giúp đỡ. Các giá trị được gán có thể được lấy từ mô tả đầu cuối; thường xuyên hơn họ chỉ đơn giản là mã hóa cứng. Quy ước cho các biến này yêu cầu chúng có hiệu lực trừ khi bị triệt tiêu rõ ràng, ví dụ, trong use_envchức năng ứng dụng chửi rủa . Về mặt tích cực, những biến đó có thể hữu ích khi không có thông tin đáng tin cậy. Về mặt tiêu cực, không có phương pháp thuận tiện để thay đổi các biến đó.

Các resizechương trình (một tiện ích được cung cấp với xterm) có thể sử dụng vt100 kiểu dãy thoát báo cáo vị trí con trỏ để xác định kích thước màn hình. Điều này có thể được chạy từ dòng lệnh; (một lần nữa) không có cách thuận tiện để làm điều đó tự động. Là một hiệu ứng phụ, resizecập nhật thông tin trên các hàng / cột được nhìn thấy bởi stty. Việc sử dụng nó để cung cấp các biến môi trường cập nhật chủ yếu hữu ích cho các trường hợp như thế này, ở đâu LINESCOLUMNS được đặt và nên được cập nhật.


3

Đây là một giải pháp khác phù hợp với tôi trên hệ thống nhúng Linux của tôi (Overo chạy Angstrom). Tôi chỉ chạy nó từ tệp .bashrc của tôi. Tôi không muốn sử dụng thay đổi kích thước vì yêu cầu cài đặt một số gói X và tôi không muốn điều đó.

Nói với Raspberry Pi rằng thiết bị đầu cuối của bạn lớn hơn 24 dòng | Blog suy nghĩ nông


3
Xin đừng chỉ đăng một liên kết: bao gồm các chi tiết có liên quan để thông tin cũng có sẵn ở đây ...
jasonwryan

1
Quá tệ, nó cần Python.
Craig McQueen


1

Khi chạy một phiên shell trên một dòng nối tiếp, việc gọi resizelệnh bên trong phiên đó là đủ - sau khi thiết lập kết nối và sau mỗi lần thay đổi hình dạng đầu cuối.

Các resizelệnh là một phần của xterm nhưng không phụ thuộc vào X11. Ví dụ, trên Fedora, nó được đóng gói riêng như xterm-resize.

Cách thức hoạt động: lệnh thay đổi kích thước đo chiều cao / chiều rộng thông qua một số chuyển động con trỏ và sau đó gửi các giá trị đó đến thiết bị đầu cuối thông qua các chuỗi thoát.

Với shell như zsh, điều này cũng tự động cập nhật các biến LINESCOLUMNSbiến (thay vào đó, người ta có thể đánh giá các câu lệnh xuất mà các lệnh được in ra thiết bị xuất chuẩn).

Tại sao điều này là cần thiết: với phiên cục bộ hoặc ssh, thiết bị đầu cuối có thể báo hiệu phiên về thay đổi hình học (xem SIGWINCH). Cơ chế này không hoạt động trên một kết nối nối tiếp.


0

Đây là chức năng thay đổi kích thước đơn giản và nhanh chóng chỉ hoạt động cho bash. Nó được sửa đổi từ res2 của phk, sử dụng bash's read -d delimđể tránh thời gian chờ kết thúc đọc.

resize() {
  old=$(stty -g)
  stty -echo
  printf '\033[18t'
  IFS=';' read -d t _ rows cols _
  stty "$old"
  stty cols "$cols" rows "$rows"
}
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.