select syntax violates the POLA

2021-04-01 Thread greywolf
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: netbsd
Compiler: gcc
Compilation CFLAGS: -O2 -I/usr/local/include -D_FORTIFY_SOURCE=2 -I/usr/include 
uname output: NetBSD eddie.starwolf.com 9.99.81 NetBSD 9.99.81 (EDDIE) #9: Tue 
Mar 23 19:13:25 PDT 2021  greyw...@eddie.starwolf.com:/sys/native/compile/EDDIE 
amd64
Machine Type: x86_64--netbsd

Bash Version: 5.1
Patch Level: 4
Release Status: release

Description:
The 'select' directive's syntax does not correspond to the rest of the 
shell's syntax.
I am not sure if this is by design; if it is, let me know and I'll go 
away.

The following is valid shell code:

d=($(ls /usr/src/pkg/*/$1));
n=${#d[@]};

if ((n > 1)); then {
echo "Ambiguous dir specification";
exit 1;
}
else {
dir=${d[0]};
} fi;

cd ${dir} &&
make clean && {
make update ||
make install;
}

I'd like to replace the first part of the if/else/fi with:

if ((n > 1)); then {
select dir in ${d[@]}; do {
break;
} done;
}
else { ...

...but select breaks on the "} done;" syntax that works with, e.g.,

while sleep 5; do {
date;
} done;

until [ -f ${tmpfile} ]; do {
sleep 5;
} done;

for dir in ${d[@]}; do {
echo ${dir};
} done;

This violates the POLA, from my point of view.

Repeat-By:

d=($(ls /usr/src/pkg/*/$1));
select dir in ${d[@]}; do {
break;
} done;



Re: select syntax violates the POLA

2021-04-01 Thread Greywolf

On 4/1/2021 9:16, konsolebox wrote:

On Thu, Apr 1, 2021 at 11:25 PM  wrote:


 if ((n > 1)); then {
 echo "Ambiguous dir specification";
 exit 1;
 }
 else {
 dir=${d[0]};
 } fi;


The grouping is unnecessary or should be separate from the first class
syntax.  Bash is not C or Go and shouldn't be written like it.



I didn't ask for your opinion on my coding style.

It's worked correctly for 25 years.  I have my reasons.



Re: select syntax violates the POLA

2021-04-01 Thread Greywolf

On 4/1/2021 9:58, Robert Elz wrote:

 Date:Thu, 1 Apr 2021 11:36:14 -0400
 From:Greg Wooledge 
 Message-ID:  

   | On Thu, Apr 01, 2021 at 01:36:59AM -0700, greyw...@starwolf.com wrote:
   | >   The following is valid shell code:
   | >
   | >   d=($(ls /usr/src/pkg/*/$1));
   |
   | Syntactically valid, but semantically wrong


Mr. Elz!  Long time!  I remember reading your posts 30 years ago!

[ much other ado elided ]


   | "${d[@]}" with quotes.

Again, yes, but in practice here, not needed.

   | What purpose do the extra curly braces serve?

Good question, wondered that myself.   Note that if they were omitted
the odd syntax issue wouldn't have arisen, as the done would follow "break;"
and be recognised.


Unfortunately the way bash has implemented arrays, $d[@] doesn't do The
Right Thing.

Or do you mean my coding style (which has been valid for over 25 years)?
(why's everyone bagging on my style and ignoring my original point, the
outlying brokenness, anyway?)

I started using the curly braces because every (worthwhile) editor has a
paren-match function which shows you the matching brace at the other
end, and I was tired of searching for which conditional component
(while, if, for, and so on) was missing its closing word.  This helps me
immensely.



After all that, and ignoring select's syntax (it was invented by
ksh, long long ago, and isn't going to change) it is a dumb interface
that can always be coded better using other mechanisms.   And when you
do that you can allow for much more flexible input than just the line
number the select demands.


Indeed, I have written such animals from scratch; I just thought I'd try
out select and was astonished when

select x in ${list}; do {
break;
} done;

was the only one that failed.



If you avoid select, and avoid arrays, then any Bourne style shell will work.
So, do that.


I will also note that the arrays don't give me grief in the least. :)




kre



Thank you so much for your response!  You got exactly what I was after!

--*greywolf;



Re: select syntax violates the POLA

2021-04-01 Thread Greywolf

Hi, Chet!  I've read a lot of your posts long ago, as well!

On 4/1/2021 8:57, Chet Ramey wrote:


It's more like `select' doesn't inherit some of the shell's special cases.


    select dir in ${d[@]}; do {
    break;
    } done;

>>
...but select breaks on the "} done;" syntax 


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. Some of the other compound commands have special
cases, mostly inherited from the Bourne shell, to allow it.


Firstly, thank you for your concise reply.

I discovered that making it '}; done;' as you suggested here worked,
shortly after my broken astonishment :).

kre mentioned that it's a ksh holdover.  This explains a great many
things considering how horribly broken I have found ksh to be (and the
weak arguments supporting that brokenness; among them, the need to
say 'fg %4' instead of merely being able to say '%4'; the requirement
to have ${var[ix]} instead of honouring $var[ix] with regard to arrays
is another one).

Lastly, thanks for not bagging on my coding style.  It was somewhat
intentional, somewhat accidental when I started using it 25 years back.
Being able to paren-match my for-in-do-done, while/until-do-done,
if-elif-else-fi has been a timesaver.  It not only helps me spot missing
closures, it helps me spot missing quotes.

[I think the only thing I wish would be enhanced and accepted further
was for it to work with case-esac, but that hasn't changed in 25 years,
either, and it's minor, so I'm not holding my breath. :) ]

Cheers,

--*greywolf;




Re: select syntax violates the POLA

2021-04-01 Thread Greywolf

On 4/1/2021 16:03, Robert Elz wrote:

Partly because if you didn't use the braces, the issue wouldn't have arisen.
(And because to most of us it just looks weird, kind of like people
who write functions like f() {( commands to run in a subshell )}
where the braces do nothing useful at all. and should just be omitted.


Heh.  Nope -- if it's to be subshelled, I do not use the braces
around the parens.


that's not an unreasonable use explanation.  I find that a consistent
style and correct indentation work well enough for this though.


I have a consistent style and indentation ("correct" is subjective) :)


... so '} done' should work correctly,
always, if the '}' is a reserved word, and a ';' or newline between them
should not be needed.


Which was why I was kind of taken aback when it failed.


kre


    Thank you, again!

--*greywolf;




Re: select syntax violates the POLA

2021-04-05 Thread Greywolf

On 4/4/2021 23:13, konsolebox wrote:

On Sat, Apr 3, 2021 at 1:09 AM Robert Elz  wrote:

   |  [[ ]] 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.


Stop suspecting and read the source code.  Look at parse.y starting at
line 2150.  They are labeled as "Reserved words".




[[ and ]] behave like reserved words requiring whitespace between
themselves and their operands.  (( and )) do not carry that restriction;
within (( )), neither do any of */%^&|+- (or their respective OP=),
nor == || && !.  This effectively classifies (( )) as operators.

But we've drifted considerably afield.

    --*greywolf;



Re: select syntax violates the POLA

2021-04-05 Thread Greywolf

On 4/1/2021 8:57, Chet Ramey wrote:

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. Some of the other compound commands have special
cases, mostly inherited from the Bourne shell, to allow it.


I don't know that I'd call them "special cases" if sh has pretty much 
condoned it from the get-go; 'select' is the outlier, from my POV.


--*greywolf;




Re: select syntax violates the POLA

2021-04-05 Thread Greywolf

On 4/2/2021 8:21, konsolebox wrote:
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.



I'd call it less a compromise than a mechanism; of all listed,
{} represents a block of code in the current shell, () represents
a block of code in a subshell...

but if you want to go down that track, it's kind of interesting to note
that {} on a single line demands a ; before the }, while () prohibits
it. This also seems inconsistent to me, but not at the same level of
egregious brokenness as select.

    --*greywolf;



Re: select syntax violates the POLA

2021-04-05 Thread Greywolf

On 4/5/2021 6:27, Chet Ramey wrote:

On 4/5/21 5:06 AM, Greywolf wrote:


but if you want to go down that track, it's kind of interesting to note
that {} on a single line demands a ; before the }, while () prohibits
it. 


This isn't true:

$ ./bash -c '(echo a b c;)'
a b c

but it is the case that } is a reserved word, while ) is an operator.



D'OH!  You're right!

I was thinking

$ foo &;

Can't put a semicolon after a null statement.

My mistake.  Carry on...

--*greywolf;



Re: select syntax violates the POLA

2021-04-05 Thread Greywolf

On 4/5/2021 13:52, Chet Ramey wrote:

On 4/1/21 5:40 PM, Greywolf wrote:


Or do you mean my coding style (which has been valid for over 25 years)?



Hey, if you want to go there, `select' has been in  bash with its current
syntax for longer than that. ;-)

(A month over 27 years, if you're curious.)



HAH!  And I only just found about it very recently while perusing the
man page!  Go figure!

In any case, I apologise if, at any point, I came across as hostile
(never my intent), and I thank you for taking the time to parley.
I've learned a few things.

--*greywolf;



Re: select syntax violates the POLA

2021-04-05 Thread Greywolf

On 4/5/2021 14:21, Chet Ramey wrote:

This presented an opportunity to marginally simplify the grammar, so it's a
win all around.

The change will be in the next devel branch push.


You have my sincere gratitude.  I did not expect so much to come of it.


Chet


    --*greywolf;