25

When using the serial console of my system I always end up with $COLUMNS=80 and $LINES=24.

While I can change these variables manually it is somewhat annoying to do this any time when the client side terminal window has been resized.

Usually I'm connecting to the console using screen /dev/mytty baudrate.

Changing the $TERM environment variable to "screen" or "xterm" does not help.

Will I need to call getty with some of those instead of vt100?

Needless to say that all of this works fine, when I connect to the same machine using ssh.

26

Like the commentators before me mentioned there is no alternative to calling resize after every command, if you don't have this command and you don't want to install a package where it's in (xterm), here are two POSIX shell script that do the same using ANSI terminal escape codes:

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, in my .profile file you will find the following: [ $(tty) = /dev/ttyS0 ] && res so that the the terminal size is determined on every login over the serial line (the one I use for management), e.g. after you reboot the device.
See also the idea by rsaw in the comments to have the line [ $(tty) = /dev/ttyS0 ] && trap res2 DEBUG there instead so the resizing runs after every command (note that AFAIK it's not or not always possible on busybox though).

  • 3
    PS: To make more permanent, add [[ $(tty) == /dev/ttyS0 ]] && trap res2 DEBUG to one of the shell profile configs (e.g., /etc/profile,~/.bash_profile). This will make it be run after every single command (which would only be a good thing if you're resizing windows/panes with screen/tmux/terminal-emulator). – rsaw Dec 30 '16 at 20:24
  • 2
    After using it for a few mins I quickly realized that both res & res2 are too slow for anything but use on first-login. On my machines, they're both taking 0.5sec to finish ... making all my commands appear sluggish (when used with DEBUG trap). Whoops! Can't have that. Guess I'll be installing xterm. – rsaw Dec 30 '16 at 20:59
  • 3
    @phk xterm's resize is waaaay faster -- usually 0.002sec. – rsaw Dec 30 '16 at 21:23
  • 1
    @rsaw Oh OK, good to know, I thought it would behave similar and therefore be similarly slow. I remember that the one in some busyboxes seemed to be just as slow to me. – phk Dec 30 '16 at 21:31
  • 1
    Thanks for this standalone solution. I'm using a console-only distro that does not have x11 or xterm installed so resize is not an option. – thom_nic Jan 23 '17 at 17:30
16

Just for the record, here is the answer to this Problem (Usenet won):

Console Applications running inside virtual terminal applications (xterm, rxvt and friends) will receive SIGWINCH after a resize operation has taken place. Thus the application will be able to redraw the window etc. in the corresponding signal handler.

Unfortunately when using a serial console, there is no such mechanism.

It is however possible for the application to actively ask for the current console Window size. So the second best thing is to do this every time a command prompt is printed by the shell.

This can be achieved by first compiling a special resize executable and then using the following in bashrc:

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

Of course this will not change the console size settings in a console application during runtime.

  • 1
    Shouldn’t it be possible to run a protocol over the serial line, that does offer all the features? I mean we do have a client and a server. They could use inband escape sequences to do just about everything, and still work with a plain text serial console! – Evi1M4chine Feb 2 '16 at 14:35
  • 1
    Actually, the comment in the code makes it plain that it's not the version of resize which is installed on your system. – Thomas Dickey Feb 16 '16 at 15:23
9

"Resizable" terminals as such are a result of NAWS (Negotiate About Window Size from RFC 1073 Telnet Window Size Option).

If you are connected directly to the computer using a serial port, there is no negotiation involved, and the computer has no direct knowledge of your terminal's screen-size.

If a terminal can negotiate the size, the computer will send SIGWINCH to applications running in the terminal, telling them to update their notion of the screensize.

When the computer does not know the screensize, it typically sets the size shown by stty -a (rows and columns) to zero. For interactive use, this is a little unfriendly, and some systems use environment variables LINES and COLUMNS to help. The values assigned may be derived from the terminal description; more often they are simply hardcoded. The convention for these variables requires that they take effect unless explicitly suppressed, e.g., in curses applications use_env function. On the positive side, those variables can be useful when no reliable information is available. On the negative side, there is no convenient method for altering those variables.

The resize program (a utility provided with xterm) can use the VT100-style cursor position report escape sequence for determining the screen size. This can be run from the command-line; there is (again) no convenient way to do it automatically. As a side-effect, resize updates the information on rows/columns seen by stty. Its use for providing updated environment variables is mainly useful for cases such as this, where LINES and COLUMNS are set, and should be updated.

3

Here is another solution that worked great for me on my embedded Linux system (Overo running Angstrom). I just ran it from my .bashrc file. I didn't want to use resize because that requires installing some X packages, and I didn't want that.

Telling your Raspberry Pi that your terminal is bigger than 24 lines | Shallow Thoughts Blog

  • 3
    Please don't just post a link: include the relevant detail so that the information is available here as well... – jasonwryan May 3 '14 at 0:51
  • 1
    Too bad it needs Python. – Craig McQueen Oct 31 '14 at 4:52
1

In case you could use FreeBSD instead, there's the resizewin(1) command, which does exactly what you want.

1

When running a shell session over a serial line it is sufficient to call the resize command inside that session - after establishing the connection and after each terminal geometry change.

The resize command is part of xterm but doesn't depend on X11. For example, on Fedora it's separately packaged as xterm-resize.

How it works: the resize command measures the height/width via some cursor movements and then sends those values to the terminal via escape sequences.

With a shell like zsh this also automagically updates the LINES and COLUMNS variables (alternatively, one can evaluate the export statements the commands prints to stdout).

Why this is necessary: with a local or ssh session the terminal is able to signal the session about geometry changes (cf. SIGWINCH). This mechanism doesn't work over a serial connection.

0

Here is simple and fast resize function that works only for bash. It is modified from phk's res2, making use of bash's read -d delim to avoid letting the timeout to finish read.

resize() {
  old=$(stty -g)
  stty -echo
  printf '\033[18t'
  IFS=';' read -d t _ rows cols _
  stty "$old"
  stty cols "$cols" rows "$rows"
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.