Re: select syntax violates the POLA

2021-04-02 Thread Ilkka Virta
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)


Re: select syntax violates the POLA

2021-04-02 Thread Ilkka Virta
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

2021-04-02 Thread Robert Elz
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

2021-04-02 Thread Robert Elz
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

2021-04-02 Thread konsolebox
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

2021-04-02 Thread konsolebox
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

2021-04-02 Thread Andreas Schwab
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."