Re: [doc] LINES/COLUMNS auto-update in non-interactive shells contradicts manual
Chet Ramey <[email protected]> Wed, 13 May 2026 16:56:37 -0400
| Newsgroups | gmane.comp.shells.bash.bugs |
|---|---|
| Message-ID | <[email protected]> |
On 5/12/26 12:58 PM, Robert Elz wrote: > Date: Tue, 12 May 2026 10:24:17 -0400 > From: Chet Ramey <[email protected]> > Message-ID: <[email protected]> > > | > That is not what LINES and COLUMNS are intended to be > | > (or ever were). They're supposed to be a method for the user to > | > override the default settings for length/width, not a method to find > | > out what the default settings are. > | > | This breaks down in the face of SIGWINCH, especially when it is sent to > | a child process while job control is active, and the shell doesn't > | receive it. > > Huh? Sorry, that makes no sense at all. Please re-read what I said, and > then explain how that response is relevant. OK, let me try another way. I think the disconnect is in the notion of the `default settings for length/width' and how applications discover that, or did discover it back when these features were introduced into bash, and maybe a different view of user expectations. The behavior is longstanding, and I bet you can guess how it originated. The most recent change in this area (bash-5.0, eight years ago) was to default checkwinsize to enabled, after many user requests (dating from 1996!) and distros setting it in their standard shell startup files (I think Debian was a, um, pioneer in this area). Say there is a user who happens to run some applications that use LINES and COLUMNS to determine some behavior. The user makes this happen by exporting LINES and COLUMNS from the shell, so they don't have to specify values every time they invoke the program. This was the original motivation for having the shell set LINES and COLUMNS in the first place -- `less' and `vi' were two of the major drivers. Even today there are applications that don't use tcgetwinsize/tcsetwinsize or their equivalent ioctls, though many fewer than there used to be. Now say the user resizes their terminal while the shell is running. If the shell doesn't catch SIGWINCH and update LINES and COLUMNS, the user has to reset their values so the application they're interested in using has the right values the next time they run it. So the shell catches SIGWINCH when interactive and sets LINES and COLUMNS, and the user expects the shell to do that for them. Some shells do this even when not interactive, but bash doesn't. (If the user employs something like X11 `resize' to do this, like many of us used to before shells did, that will export LINES and COLUMNS for them, btw.) The next time, the user resizes their terminal while running a screen editor, maybe to view a long line. The shell doesn't get the SIGWINCH, so it doesn't update LINES and COLUMNS from the SIGWINCH handler, but the user's expectations don't change: they want their application to get the updated window size, and the shell is in a position to do it rather than force the user to manually reset or specify LINES and COLUMNS. So this was the original motivator for checkwinsize. Bash is one of those applications, since it uses COLUMNS to determine how to print the lists for `select'. It's always been documented to do this; if you want to blame someone for it, blame Korn. Users have the valid expectation that `select' will use the current window size, as stored in COLUMNS, with a way to override it by temporarily setting COLUMNS. Maybe this isn't the answer you wanted, and maybe you consider these applications broken for the modern era, but there are still existing applications that use only LINES and COLUMNS, even though bash has been doing this since 1992. > It seems as if you're trying to explain how checkwinsize works, and why, > which has nothing whatever to do with the primary problem. So the primary problem is that user expectations don't align with what the standard says? Or that we have different ideas of what those user expectations are? Or that the behavior dates from a time when conditions were different? > There's nothing > at all wrong with having something like checkwinsize being run by the shell, > it just shouldn't be setting LINES or COLUMNS (it could set BASH_LINES and > BASH_COLUMNS if you wanted ... see below.) That doesn't help anything. > > | Since bash uses COLUMNS (for select, if you disregard everything else), > > As it should (assuming one admits select should even exist, but that > question isn't relevant here) and so should lots of other commands, eg > kill (for kill -l) should use it as well, for working out how wide the > output should be (how many columns of signal names fit on each line). Maybe it should, but it doesn't now. > That is, if COLUMNS is set, use it, unless a command line option has > set something different, in which case use that. Otherwise find out > from the system (perhaps using tcgetwinsize() ) what the size is. > If that fails, (and a terminal is in use) perhaps look for the size > info corresponding to TERM (but if a terminal is in use, tcgetwinsize > will probably work). If all else fails, pick some reasonable default. I agree this is the way things should be done, but there are applications out there that simply don't (or, mostly, didn't) do it that way. > > | it is an unnecessary burden for the user to have to manually reset > | COLUMNS after a window size change. > > Why would the user ever want to do that? See above. > The user is only supposed > to set those when a particular size is required, if that is the case, > what the actual window size might be is irrelevant, and so are any > changes made to it. This assumes that the user's application falls back to something other than LINES and COLUMNS to determine the appropriate window size. That was not the case when bash started setting LINES and COLUMNS. > > | That's the whole rationale for `checkwinsize' to exist. > > And that's fine, it just shouldn't set LINES and COLUMNS. See above. > > | > The standard is quite clear: [...] > > | This assumes that something will change LINES and COLUMNS in response to > | changes to `the terminal characteristics'. > > It assumes nothing of the kind. Or it assumes that applications use something other than LINES and COLUMNS to determine the `true' window size. It might be less common than it was when this whole thing started, but there are a non-zero number of programs that do that. Not only that, since this behavior has existed for more than 30 years, there are a non-zero number of users who expect the shell to do what it does, on the theory that it is part of the `user environment' the shell maintains and communicates through variables. > | Except that we live in 2026, not 1992. That language has survived > | essentially unchanged since the first issue of 1003.2, > > Which if anything is exactly the point. There's never been any > question what LINES and COLUMNS are intended to be for, and it has > *never* been to provide information about the size of anything. > They are directive variables, and always have been, not informative. It was never absolute like that. I know what the standard attempted to say, but even at that time there were many applications that simply did not do that. Bug reports about those applications similar to what I described above were why bash started doing this in the first place. Vendors would even change their systems to make sure that LINES and COLUMNS were in the shell's initial environment (looking at you, HP) so users wouldn't have to do it, assuming that the shell set the variables. And now the behavior is entrenched. > > | but expectations have changed. > > What has changed is that some shells (probably starting from ksh) > decided to change the meaning of LINES & COLUMNS and use them to > provide information, which was never their purpose. That's unfortunate. I don't agree. The initial problem was applications that used LINES and COLUMNS to set an initial window size, and didn't fall back to anything else. Bash didn't start out doing this -- it was the result of user complaints. > Other shells (yash, bosh, dash (and other ash derived shells) don't). And some others (mksh) do. Those other shells probably don't have the burdens of earlier eras. > How well that works depends upon the application, and > whether the user is asking for more, or for less, than actually exists, > but that's all up to the user. Sure, that's the rub. > What burden? If some application is only able (or willing) to use > LINES/COLUMNS to get size information, and it needs that info, it is broken. Sure. There are broken applications out there, and always have been. The shell should help the user if it can. > In practice, I almost never have LINES or COLUMNS set, except inside bash, > and they are not exported there (they're certainly not in any environment > when bash is started) Yes, bash doesn't export them unless they're in the initial environment (neither does ksh, fwiw). That's up to the user. > - and I've never had an issue with any application > needing to be told somehow what the terminal size is (many like to be told > how big I would like them to be, when they create a window, but except for > terminal emulators, that info is usually conveyed in pixels, not char sized > units). Good. > The way ksh (and bash, etc) are using LINES and COLUMNS > is exactly this. I'm saying you have it backwards. The bash behavior is the result of people asking for it to work with applications that needed it, not that bash decided to do this and forced applications to go along. And now users have expectations that bash will continue to behave as it has. > But even if it doesn't (dash, yash, the NetBSD sh, don't) and a user > needs that info, then as [email protected] just said: > > >> POSIX.1-2024 adds "size" request to stty(1): It's about time. But bash has been doing what it does for quite a while (checkwinsize came in 1996) and has a set of its own user expectations. > > So a user (or script) can just do > > tsize() { set -- $(stty size); rows=$1 cols=$2; } > trap tsize WINCH > tsize People get unhappy when they have to change their scripts because the shell's behavior changes, no matter what the reason. I'm reluctant to change the default setting of checkwinsize in non-interactive shells for just this reason. It's a delicate balance. > Any application which cares about terminal sizes already needs to deal > with this issue, as the terminal size can change while they are running, > and the LINES and COLUMNS variables they may have been provided with in > the environment certainly do not magically alter when that happens. The usual way to deal with that -- even back in the day, of course -- was to use the user's preferred settings (LINES/COLUMNS) initially and track any window size changes after that. But see above. > It is in general unfortunate that a standard method to get this info has taken > so long to eventuate, but that does not excuse having usurped the perfectly > simple (and well defined) definitions of LINES and COLUMNS to use them > "just because there is nothing else defined". And the result of this delay is that we have entrenched behavior and user expectations. > Unfortunately, now we > have a mess, with some shells setting those vars, totally inappropriately, > and others not (following the standard). What we have is the result of some shells having to deal with problems other shells did not. This might have been a useful discussion in, say, 1996. > > And lastly, wrt your slightly earlier message: > > [email protected] said: > | Since many (most) terminal emulators set LINES and COLUMNS in the > | environment they provide to the shell they invoke, > > There might certainly be some that do that, but nothing I have here > acts that way. xterm certainly does not. Nor does rxvt. No, see my other message. Chet -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRU [email protected] http://tiswww.cwru.edu/~chet/