Date: Tue, 14 Feb 2023 11:04:48 -0500 From: Chet Ramey <chet.ra...@case.edu> Message-ID: <8be447ca-5416-a64f-7e62-1e61102e8...@case.edu>
| "Special builtin" is not a particularly useful concept I disagree - most of the time the difference doesn't matter much, but that the special built-ins cause the shell to exit if they fail means that script writers don't need to do things like break || exit 99 just in case something is wrong with the script, and the break doesn't happen in a loop, and so is an error. With it being a special built-in the script simply exits at that point, otherwise if the script writer hasn't tested for the error, the script just keeps running to the next command, which is fairly clear is not what was intended. That's somewhat esoteric, as things like break/continue/ ... rarely ever fail. But for "eval" it matters, consider eval '| grep foo' || { # code to handle what happens when foo isn't there } That's not likely as written, but could happen from eval " $command | grep foo" || ... if "$command" turns out to be unset or null at this point due to some bug or other. That results in a syntax error from eval, which is a special built-in failure, which should cause the shell to exit. Allowing it to continue with just a failure status means the script believes that the grep failed. That is, I don't really think that (from an earlier message): | the only rationale for why those particular ones were chosen | is "this is what the Bourne shell did." or perhaps stated better, yes, that is more or less why they were chosen, but that makes it seem like some of the other (bizarre) things that the Bourne shell did (probably as a code space saving mechanism), whereas I suspect that this division was probably more carefully considered from the start. The special built-in commands are commands that could almost be reserved words, and often would be, but were implemented as commands instead (and probably are better that way). kre