bug-bash
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]