[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: !(.pattern) can match . and .. if dotglob is enabled
From: |
Nora Platiel |
Subject: |
Re: !(.pattern) can match . and .. if dotglob is enabled |
Date: |
Sun, 6 Jun 2021 02:42:31 +0200 |
Thanks again for the info. Now I understand why `.' and `..' are handled
separately, and I can imagine the complexity.
> The "matched explicitly" refers to the previous sentence, which talks about
> the `.' at the start of a filename or path component needing to be matched
> explicitly by a pattern beginning with a `.' or containing a `.' at the
> right spot (after a `/'). I can add language to clarify that.
What about this?
| When a pattern is used for filename expansion, the character `.' at the
| start of a filename or path component must be matched explicitly by a
| corresponding `.' at the start of the pattern or after a `/', unless the
| shell option dotglob is set. The character `.' at the start of the
| filenames `.' and `..' must always be matched explicitly, even if dotglob
| is set. In other cases, the `.' character is not treated specially.
> > $ echo !(.foo)
> > bar
>
> There is an equally compelling argument to be made that `.' and `..' should
> be included in the results from the second example, since they do not match
> the pattern `.foo'. The question is how much `not matching' you want.
> `dotglob' only affects the `matching' state. That's the essence of where we
> started with this.
Yes, it all depends on the "universal set" from which the matches of the inner
`pattern-list' are subtracted.
But in the current implementation, the inner matches are subtracted from:
- all files, if dotglob is set
- all except dot files, if dotglob is unset
The inclusion of `.' and `..' when dotglob is set, seems inconsistent with the
exclusion of dot files when dotglob is unset.
I think it would be most intuitive and useful to define the universal set to be
whatever `*' can expand to.
I.e.
- all except `.' and `..', if dotglob is set
- all except dot files, if dotglob is unset
> I'm not averse to changing the current behavior. This is a niche case.
> Then instead of figuring out language to describe the current behavior,
> let's figure out language to describe the desired behavior.
I would want to limit as much as possible the cases where a path component can
expand to `.' or `..', which is always undesirable, but also remain consistent
with non-extended globbing and keep it simple.
With dotglob set, we can use `[.]' to match a starting dot without the risk of
including `.' and `..'.
I always use `[.]*' instead of `.*', so it comes natural that I need to use
`@([.]*|foo)' instead of `@(.*|foo)'.
But normally there's no need to protect the dot in `.foo*', so it doesn't come
natural that I need to protect it in cases like `!([.]foo*)' or `@([.]foo*|??)'.
With dotglob unset, the current behavior seems fine.
> Your English is fine. You want to take a shot at a sentence or two
> describing your desired behavior? It should not take more than that.
About the behavior of the extended operators ?,*,+,@ (with my proposed changes
when dotglob is set), I'm not sure there's a need for explanation. I think it
comes natural if you mentally translate the extended pattern into a sequence of
non-extended patterns.
About `!()', we could say:
| The `!()' operator will never match the character `.' at the start of a
| filename, unless the shell option dotglob is set. Even if dotglob is set,
| it will never match the character `.' at the start of the filenames `.'
| and `..'.
Or:
| The `!()' operator can only match strings that can be matched by `*', so
| the inclusion of filenames starting with the character `.' is affected by
| the shell option dotglob in the same way.
Regards,
NP