On Tue, Dec 2, 2025 at 2:50 PM Chet Ramey <[email protected]> wrote: > > Martin Wheatley <[email protected]> wrote: > > > I have recently identified a failure mode in bash(1) scripts that has > > plagued us with random process failures for over 20 years! > > > > The read(1) built-in command has the -t option to specify a timeout on > > the read and it appears that the TMOUT variable is also honoured as an > > alternative if it is defined (and this is where I think there is an issue). > > Yes, this is documented behavior that has existed for many years.
Another little gotcha lurking about, documented or no. > > Since TMOUT can be inheritted from a much 'higher' process a script has > > no knowledge about whether it has been set or not nor whether the value > > is appropriate for the script. > > If your script is self-contained, and presumably knows what is appropriate > for it, why not continue to do as you describe: > > > I can (and now do) 'unset TMOUT' where I know my scripts are > > susceptible to this issue but would ask that you consider whether TMOUT > > should ever be considered when reading from a pipe. > > I see arguments both ways. I think it's reasonable not to change the > longstanding behavior, since you have identified a way around it. Bash scripts don't accept IFS exported from the environment. It's always initially set to $' \t\n'. Scripts could similarly not accept some other variables with special meaning to the shell from the environment, instead leaving them unset regardless of the environment. CDPATH and TMOUT seem like strong candidates for this treatment. Or in any case, now I've modified the boilerplate at the top of my important scripts to unset both of those. Already knew about CDPATH.
