Configuration Information:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -O2 -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -Wall uname output: Linux fairybrains 5.15.0-173-generic #183-Ubuntu SMP Thu Mar 27 13:22:53 UTC 2025 x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Bash Version: 5.1
Patch Level: 16
Release Status: release


Description:
The bash(1) manual states that LINES and COLUMNS are "automatically set
... in an interactive shell upon receipt of a SIGWINCH". In practice,
both variables are also updated in non-interactive shells whenever
the shell evaluates a command that queries terminal geometry via
ioctl(TIOCGWINSZ), because checkwinsize is enabled by default since
bash 4.3 and applies regardless of interactive mode when a controlling
TTY is present.

This silently breaks scripts that use LINES or COLUMNS as user variables
(e.g. as array names): the array is converted to a scalar and its
[0] element is overwritten with the current terminal height/width.
The behavior depends on whether the script's stdin is a TTY, making
it irreproducible under ssh-without-tty or under cron, but reliably
reproducible from an interactive login.


Repeat-By:
$ cat > /tmp/demo.sh << ‘EOF’
#!/bin/bash
LINES=()
LINES+=(“hello”)
echo "BEFORE: ${LINES[0]}”
ss -tln >/dev/null 2>&1   # any command that calls ioctl(TIOCGWINSZ)
echo "AFTER:  ${LINES[0]}”
EOF
$ bash /tmp/demo.sh                 # from a terminal
BEFORE: hello
AFTER:  73                          # current terminal height
$ ssh user@host 'bash /tmp/demo.sh' # without -tt: no TTY allocated
BEFORE: hello
AFTER:  hello                       # works as documented


Fix:
A documentation patch clarifying that LINES/COLUMNS may be updated in
any shell where checkwinsize is enabled and a TTY is available, not
only interactive shells. Suggested wording for the LINES entry:

  LINES  Used by the select compound command to determine the column
         length for printing selection lists.  Set automatically when
         the checkwinsize option is enabled (default since bash-4.3)
         and the shell receives a SIGWINCH or evaluates a command
         that queries terminal geometry, regardless of whether the
         shell is interactive.  Scripts using LINES or COLUMNS as
         ordinary variables (especially as arrays) may have their
         contents overwritten unexpectedly.

(analogous wording for COLUMNS)


—
Ilya Tsoy
github.com/ilvits

Reply via email to