Re: select syntax violates the POLA
On Apr 02 2021, Robert Elz wrote: > Date:Thu, 01 Apr 2021 21:33:31 -0400 > From:wor...@alum.mit.edu (Dale R. Worley) > Message-ID: <874kgpqxlg@hobgoblin.ariadne.com> > > | I was going to ask why "else {" works, > > Wrong question. That one is easy. What follows > 'else' is a list and the simplest form of a list > is a simple command, which starts with a command > word, so reserved words are always going to work > there, even without the "follows a reserved word' > rule. > > The right question would be why '} else' works. The two case are not really different, they are covered by the same rule: This recognition shall only occur when none of the characters is quoted and when the word is used as: * The first word following one of the reserved words other than case, for, or in Andreas. -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different."
Re: select syntax violates the POLA
On Fri, Apr 2, 2021 at 11:41 AM Robert Elz wrote: > > Date:Thu, 01 Apr 2021 21:33:31 -0400 > From:wor...@alum.mit.edu (Dale R. Worley) > Message-ID: <874kgpqxlg@hobgoblin.ariadne.com> > > | I was going to ask why "else {" works, > > Wrong question. That one is easy. What follows > 'else' is a list and the simplest form of a list > is a simple command, which starts with a command > word, so reserved words are always going to work > there, even without the "follows a reserved word' > rule. > > The right question would be why '} else' works. Indeed. This inconsistency should be fixed and prevent people from using it wrong. `}; else` should work but not `} else` just like how `{ :; } :` doesn't. -- konsolebox
Re: select syntax violates the POLA
On Fri, Apr 2, 2021 at 3:03 PM Andreas Schwab wrote: > > On Apr 02 2021, Robert Elz wrote: > > > Date:Thu, 01 Apr 2021 21:33:31 -0400 > > From:wor...@alum.mit.edu (Dale R. Worley) > > Message-ID: <874kgpqxlg@hobgoblin.ariadne.com> > > > > | I was going to ask why "else {" works, > > > > Wrong question. That one is easy. What follows > > 'else' is a list and the simplest form of a list > > is a simple command, which starts with a command > > word, so reserved words are always going to work > > there, even without the "follows a reserved word' > > rule. > > > > The right question would be why '} else' works. > > The two case are not really different, they are covered by the same > rule: > > This recognition shall only occur when none of the characters is > quoted and when the word is used as: > > * The first word following one of the reserved words other than > case, for, or in > That's not a rule but a special compromise. [[ ]] and (( )) are a form of reserved words themselves just like () and {} as they can be used multi-line but they aren't allowed to be adjacent to else et al without a semicolon. [[ ]], (( )), {}, and () are practically just commands with first-class parsing that consistently have to end with a semicolon if followed by another reserved word or command. -- konsolebox
Re: select syntax violates the POLA
Date:Fri, 2 Apr 2021 23:06:40 +0800 From:konsolebox Message-ID: | > The right question would be why '} else' works. | | This inconsistency should be fixed and prevent people from | using it wrong. `}; else` should work Yes. | but not `} else` No, that should work too. The "then" part of an if statement (which is what the '}' is the last element of in that example, obviously, takes a list if_clause : If compound_list Then compound_list else_part Fi and the list (compound_list in posix speak) can be compound_list : linebreak term where linebreak is an optional newline (but is before the term anyway so isn't relevant here as we're looking at the ending, not the beginning) and term can be term : and_or and and-or can be and_or : pipeline and pipeline can be pipeline : pipe_sequence and pipe_sequence can be pipe_sequence : command and command can be command : compound_command and compound_command can be compound_command : brace_group and brace_group is brace_group : Lbrace compound_list Rbrace ; Observe that following that sequence, there is no separator (';' etc) required between the Rbrace ('}') that terminates the brace_group which is the compound_command which is the command which is the pipe_sequence which is the pipeline which is the and_or which is the term which is the last thing in the compound_list after which "else" follows immediately. Of course, all the "can be" rules above have alternatives, other things are possible, in particular, the full rule for compound_list is compound_list : linebreak term | linebreak term separator ; so it is obvious (very obvious) that a separator is allowed after the term, but not required. | just like how `{ :; } :` doesn't. That is an entirely different thing. ':' isn't a reserved word, so the reserved word rule isn't relevant, and sequential commands (like the group, and the second ':' in that example) need to be separated by some kind of separator (';' '&' or newline). And from your other message: | That's not a rule but a special compromise. No, it is a rule, it is required to allow the 'else' in the example above to be a reserved word, otherwise it would just be a normal word, and that would be a syntax error. | [[ ]] and (( )) are a form of reserved words themselves Those are bash specials, and I am fairly sure that (( and )) will be operators, not reserved words (they cannot really be the latter, as ( and ) are operators) and I suspect that [[ and ]] might be as well, but there I'm not sure. operators and reserved words are quite different things. Operators (unquoted) are recognised as themselves wherever they appear. | just like () and {} '(' and ')' are operators. '{' and '}' are reserved words. | as they can be used multi-line but That has nothing to do with anything. Anywhere where the grammar allows linebreak or separator (maybe more) can be used multi-line. Anwhere those things are not in the grammar, line breaks (not counting \newline or quoted newlines) are not permitted. | but they aren't allowed to be adjacent to else et al without a semicolon. Nonsense. | practically just commands with first-class parsing that consistently | have to end with a semicolon No, they don't (even if you extend semicolon to include ampersand and newline). | if followed by another reserved word or command if followed by another command yes, as the separator is just that, a separator, it separates different commands, it is not a terminator (unlike the ';' in C expression statements for example). Where reserved words are allowed entirely depends upon what the grammar allows. And as above, "} else {" is a perfectly valid sequence as part of an "if" statement. kre
Re: select syntax violates the POLA
Date:Fri, 02 Apr 2021 09:02:40 +0200 From:Andreas Schwab Message-ID: <87o8exp3sf@linux-m68k.org> | The two case are not really different, they are covered by the same | rule: Yes, I knew that ... but they are different, as in the "else {" case the '{' is in the command word position (which "else" is not in "} else") and so is a reserved word for that reason as well. Everyone (well, everyone who understands something about shell syntax) knows the "reserved words happen in the command word position" rule, it is what makes echo if I do it while the case is ! done then in payment for ... work without there being anything which is a reserved word there, but (as is obvious by some of this discussion) not everyone realises the consecutive reserved words rule exists. kre
Re: select syntax violates the POLA
On Fri, Apr 2, 2021 at 2:04 AM Robert Elz wrote: > chet.ra...@case.edu said: > | Yes, you need a list terminator so that `done' is recognized as a > reserved > | word here. `;' is sufficient. Select doesn't allow the `done' unless > it's > | in a command position. > > isn't really all that appealing as an explanation. select isn't part > of the standard, so its syntax is arbitrary, which means that nothing can > really be considered wrong, but while we often think of reserved words > (not counting the special cases in case and for statements) as only working > in the command word position, that's not how it really is. They work > there, > they also should work following other reserved words (most of them, but > '}' is not one of the exceptions). so '} done' should work correctly, > always, if the '}' is a reserved word, and a ';' or newline between them > should not be needed. > FWIW, it works in the other shells I know that support select: $ cat select.sh select x in foo bar; do { echo $x; break; } done; $ for sh in bash ksh mksh zsh; do echo "== $sh"; $sh select.sh <<< 1; done == bash select.sh: line 5: syntax error near unexpected token ‘done’ select.sh: line 5: `} done;' == ksh 1) foo 2) bar foo == mksh 1) foo 2) bar #? foo == zsh 1) foo 2) bar ?# foo
Re: select syntax violates the POLA
On Thu, Apr 1, 2021 at 7:59 PM Robert Elz wrote: > Alternatively > d=( $( ls -d /usr/src/pkg/*/$1 ) ) > or just > d=( $( printf %s\\n /usr/src/pkg/*/$1 ) ) > > Just to be sure.Personally I'd do > > set -- /usr/src/pkg/*/$1 > Just the glob is fine in the array assignment, it splits and globs the same as in arguments to 'set': d=( /usr/src/pkg/*/$1 ) (If there was any context that splits but doesn't glob, this isn't one)