Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Mix and match parameter expansion flags and sub-scripting flags + quoting

On Fri, Dec 29, 2017 at 12:43 PM, Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>

> On Fri, Dec 29, 2017 at 7:29 AM, Jim <linux.tech.guy@xxxxxxxxx> wrote:
> > Hello,
> >
> > The intent is, using only "native zsh" tools, return the 'shell'
> > as set in /etc/passwd for my own $USER without using any external
> > utilities, gnu or otherwise. As in UNIX/Linux, zsh also has more then
> > one way of doing the same thing. So as a training exercise I decided
> > to use as many variants as I could to do the same thing. In the process
> > I found that what I though would work, did not return the intended
> > result.
> I haven't gone through your cases in any detail, but there are almost
> certainly three things causing your problems:
> (1) Nested expansions plus quoting cause an array in the inner
> expansion to be joined into a string in most cases, unless you use
> special syntax to preserve the array
(2) Single-element arrays behave like scalars (strings) in several cases
(3) Subscript syntax applies to scalars, to extract substrings
I can see this from my testing.

> Those last two put together can cause a lot of head-scratching.
> I believe I do my fair share, and not only on this.

> Figuring out at what level of a nested expansion you need to add (A)
> or (@) is the other part of the equation.  Sometimes you need to add
> an extra level of nesting just to force (A) to be applied to the
> correct value.
> AFAICT ..."${(f)"$(<TestFile)"}"... is working but it is one of those
head-scratching moments. Inner quotes, outer quotes or both inner and
outer quotes? Testing of all three, all work. I don't believe the problem
is there. The issue appears to be around the matching. The following two
statements appear to return the same line/string/scalar.


Applying the subscript to the scalar returns the output I expected in both

print -l \"${shell}\" ${(t)shell} ${shell[(ws/:/)7]}

When adding the same subscript to both statements, using "nesting",
the resulting output is different for each. The first appears to return an
empty scalar, whereas the second returns the expected output.

shell=${${(M)"${(f)"$(<${TestFile})"}":#*:${UID}:${GID}:*}[(ws/:/)7]} ;
print -l \"${shell}\"

shell=${${"${(f)"$(<${TestFile})"}"[(r)*:${UID}:${GID}:*]}[(ws/:/)7]} ;
print -l \"${shell}\"

The question, for me, is why two different results, by the same subscript,
apparently the same output from each type of match? It seems logical
that both should work. Sorry if I'm being like a bulldog that won't let
go.  I do
have other ways that work, as shown above. I would just like to understand
why this doesn't work, even if it's do to my own, current, inability to
grasp the
logic of it.



Messages sorted by: Reverse Date, Date, Thread, Author