On 9/4/25 7:14 AM, Martin D Kealey wrote:
On Thu, 4 Sep 2025, 00:06 Chet Ramey, <[email protected] <mailto:[email protected]>> wrote:If you think "significant parts" of the shell's behavior are undocumented, either point them out or propose documentation patches.Looking at doc/bash.1, the following are some features which I believe are intentional, and which yet are undocumented.
Most of these are not undocumented. You point out some places that could use some clarification (see below), and at least one typo, but virtually all of these are you complaining about style and language.
Compound statements generally:• Semicolons are optional between a closing keyword (or symbol) and a non- initial keyword. By way of example, note the lack of semicolons before « then », « else », « fi », « do », « done », and « esac »:
I think this is one of the things that can use clarification. It would be good to add some more information from POSIX about when reserved words are recognized (as opposed to being treated as a WORD), specifically: 1. Reserved words are recognized as such when they follow a control operator; and 2. Reserved words are recognized as such when they are the first word following a reserved word except case/select, for, and in. It would probably be useful to add a sentence like POSIX's "[Reserved words are recognized] if the parser is in any state where only a reserved word could be the next correct token."
/Lists/ says:/A _list_ is a sequence of one or more _pipeline_s separated by one of the operators *;*, *&*, *&&*, or *||*, and optionally terminated by one of *;*, *&*, or <newline>./ This “optional” terminator is in fact /required/ if the last command in the list is (a pipeline whose last component is) a simple command, /and/ the following token is not one of « *)* », « *;;* », « *;;&* », or « *;&* ».
This is not undocumented. Can you provide an example of a simple command
that satisfies this, so I know we're talking about the same thing?
Maybe the thing to do to make it clearer is to describe how a list behaves
with each of the terminators (';', <newline>, and '&') and introduce the
compound-list, which is a sequence of newline-separated lists that can
be preceded or followed by zero or more newlines. compound-lists are
what compound commands use.
Arithmetic «for» loops: *for ((*_/expr1/_*;*_/expr2/_*;*_/expr3/_*))* [*;*] *do* _/list/_ *;* *done*• After « *continue* », _/expr3/_ will be evaluated and then _/expr2/_; that's expected by anyone who writes C, but it's not stated in the manual;It's documented in the description of `continue' ("next iteration").
• It notes that “/if any expression is omitted, it behaves as if it evaluates to 1/”. That seems overly broad, as only /_expr2_/ needs this qualification; the others can simply be indicated as optional in the synopsis, like: *for ((* [/_expr1_/] *;* [/_expr2_/] *;* [/_expr3_/] *))* [*;*] *do* / command-list/ *done*
Not undocumented.
Select loops:• synopsis indicates « *in* _/word/_ » rather than « *in* _/word-list/_ » or equivalent
Thanks, that's a typo. It should use [word ...] like the `for' description. The first paragraph has "the list of words following in."
• if « *in* _/word-list/_ » is absent, the semicolon before « do » is optional (same as « *for* » loops, but see below about an alternative definition for such lists).
Thanks, this is also a typo. The reserved word section should group `select' with `for' instead of `case'. You're the first to notice it.
Compound « case » statements:• Semicolon is permitted before « *;;* », which logically consistent with «[*(*]_/pattern/_*)* _/command-list/_ *;;* » using the definition of « _/ command-list/_ » as above, including a terminating semicolon, ampersand, or newline.
Not undocumented; a list can be terminated with a semicolon.
• The « ;; » before « esac » is optional (unless it's not preceded by a command or a semicolon). However simply marking it as optional in the synopsis is problematic unless COMMANDS is updated to mean "including the trailing semicolon/ampersand/newline", and every other synopsis adjusted to take that into account.
The synopsis already allows `case word in esac', which is really a blemish in the language, but what can you do. I don't think anyone documents that `esac' can terminate both the final command list and the case command, but I suppose I could add it.
Conditional Expressions • != does no mention pattern matching with [[
I assume you mean `not'. Not undocumented: the [[ description certainly does.
• =, == says unequivocally “True if the strings are equal”, but readers with long attention spans will later read “When used with the [[ command, performs pattern matching”.
Not undocumented: also mentioned in the [[ description.
Both of these need to be more even-handed, like:=, == for the [[ command, attempt pattern matching and return true iff successful; for the test and [ commands, compare strings and return true iff they are the same.!= same as = except the return status is inverted.
A style criticism.
Readline Notation/On some keyboards, the Meta key modifier produces characters with the eighth bit (0200) set./ Maybe document that this never applies to terminals that are in UTF-8 mode. (Also, more users are familiar with decimal 128 or hexadecimal 0x80 than with octal 0200.)
Not undocumented; a style criticism.
Expansions: • Not actually /un/documented,
Right.
• « declare », « local », and « typeset » have « -c » (capitalize on assignment) but don't docuent it.This is indeed undocumented for the same reason as the original poster's.I don't think it's particularly useful.
--
``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/
OpenPGP_signature.asc
Description: OpenPGP digital signature
