Subject: Re: ksh patterns
To: matthew sporleder <msporleder@gmail.com>
From: Chavdar Ivanov <ci4ic4@gmail.com>
List: netbsd-users
Date: 09/19/2007 23:57:45
On 19/09/2007, matthew sporleder <msporleder@gmail.com> wrote:
> On 9/19/07, matthew sporleder <msporleder@gmail.com> wrote:
> > On 9/19/07, Martin Bock <ixel@gmx.de> wrote:
> > > Hello!
> > >
> > > I am having trouble to understand ksh behaviour in context of patterns,
> > > parameters and the case-statements:
> > >
> > > The following is what I expected:
> > > ------------------------------------------------
> > > $ cat script1.sh
> > > #!/bin/ksh
> > > for file in foo bar baz; do
> > >         case $file in
> > >                 foo)    echo foo;;
> > >                 baz|bar) echo ba;;
> > >                 *)      echo default;;
> > >         esac
> > > done
> > > $ ksh script.sh
> > > foo
> > > ba
> > > ba
> > > ------------------------------------------------
> > >
> > > But with a minor modification it does not work as expected:
> > > ------------------------------------------------
> > > $ cat script2.sh
> > > #!/bin/ksh
> > > foopattern="foo"
> > > bapattern="baz|bar"
> > > for file in foo bar baz; do
> > >         case $file in
> > >                 $foopattern)    echo foo;;
> > >                 $bapattern)     echo ba;;
> > >                 *)              echo default;;
> > >         esac
> > > done
> > > $ ksh script2.sh
> > > foo
> > > default
> > > default
> > > ------------------------------------------------
> > > Note the parameters containing the patterns for the case statement.
> > > Apparently the | symbol does not do the desired magic within paramters.
> > >
> > > Now, where is the meaning of the | as in script1.sh explained in ksh(1)?
> > > While very common usage, I could not seem to find it after several reads
> > > of that manpage.
> > >
> > > Why does the version in script2.sh not work? In particular the patterns
> > > before ) in the case statement are -- according to ksh(1) -- subject to
> > > parameter expansion.
> > >
> > > VWIW, this is NetBSD 3.1
> >
> > ksh is interpreting the | literally.  This works:
> > foopattern="foo"
> > barpattern="bar"
> > bazpattern="baz"
> > for file in foo bar baz;
> > do
> >  case $file in
> >   "${foopattern}") echo foo
> >    ;;
> >   "${barpattern}"|"${bazpattern}") echo bar
> >    ;;
> >   *) echo default
> >    ;;
> >  esac
> > done
> >
> > However, that does not follow the man page:
> > "Both the word and the patterns are subject to parameter, command, and
> >  arithmetic substitution as well as tilde substitution."
> >
> > No amount of quoting or *(pattern) tricks would work for me, so I
> > think you may have a bug here.#

bash, zsh and pdksh behave this way.

The *real* thing - ast-ksh - does the *right* thing:

...(j: 1)-(100)-~% ksh93 script1.ksh
foo
ba
ba
(j: 1)-(101)-~% ksh93 script2.ksh
foo
ba
ba
...

So not all shells are born equal...



> >
>
> bash seems to behave the same way as our pdksh in this case.
>
Chavdar Ivanov