Date: Tue, 16 Feb 2021 18:19:48 +0800 From: Koichi Murase <myoga.mur...@gmail.com> Message-ID: <CAFLRLk-7rBhjMDTdmOb+0SpEJ4=6tlntt39bztj-yuw5doe...@mail.gmail.com>
| For example, this alone doesn't explain why | | $ if :; then echo A; fi if :; then echo A; fi | | (i.e., the combination "fi if") is a syntax error. That one is quite a different issue, if you look at the grammar you'll find there's no way to have 2 consecutive commands (no matter what kind of commands they are) without some kind of separator between them. The second "if" there is a total red herring, it makes no difference what word is there (except one of the legal operators in that location) - it is going to be a syntax error. The other examples given in earlier messages have one command embedded in another, there's no requirement for separators in those (and they are separators, not terminators). Your "case x in (x) if :; then echo; fi esac" is the same. kre ps: many of these strange rules all originate in the original Bourne shell's recursive descent parser, which was crammed into a very limited space, and so didn't always enforce sanity - it made sure that what needed to work worked, but cared much less about prohibiting things that are useless, and could easily have been rejected (like case statements with no patterns) had it been considered worthwhile to spend the code space needed to make that happen. Since then everyone copies so as to maintain backward compatibility ("some idiot might have written code like that, we cannot reject it"), and consequently, POSIX, which documents what actually exists, specifies it as well.