Dear zsh'ers, I'm not sure if this is a bug or a feature — but I have seen some zsh scripts break when the top level home directory (/home) is set to mode 711 and owned by root (as is common for shared home directories offered via network at our site), when nocaseglob is active. To reproduce locally, see the following example: 1) Prepare directory: mkdir foo chmod 711 foo mkdir foo/test sudo chown root:root foo cd foo/test 2) Test with caseglob: setopt caseglob echo $(pwd)(N) => Output is returned just fine. 3) Test with nocaseglob: setopt nocaseglob echo $(pwd)(N) => No output is returned. Of course, zsh can not exclude there are other directories directly inside "foo/" matching the given pattern (but with different case) since "foo/" can not be listed. However, at least the explicit match with case is known, so I'm astonished zero matches are returned. Is this expected, or a bug? Cheers, Oliver
Oliver Freyermuth wrote on Mon, 22 Aug 2022 18:02 +00:00: > 1) Prepare directory: > > mkdir foo > chmod 711 foo > mkdir foo/test > sudo chown root:root foo > cd foo/test ⋮ > setopt nocaseglob > echo $(pwd)(N) > > => No output is returned. > If the (N) is changed to (|) [that's an empty alternation], one gets a "no matches found" error. > Of course, zsh can not exclude there are other directories directly > inside "foo/" matching the given pattern (but with different case) > since "foo/" can not be listed. However, at least the explicit match > with case is known, > so I'm astonished zero matches are returned. > > Is this expected, or a bug? What would you have it do instead? Emit just one path? I don't think this would work, because if the glob expands at all, users may rely on what it _didn't_ expand to. It's perfectly within the API promise for a user to set NO_CASE_GLOB and then rely on something along the lines of the lines of «if print -l /etc(|) | grep -q /ETC; then …» (note that grep(1) is case-sensitive in this case). For comparison, consider «*(u.jrandom.)» and assume a single file in the directory returned -1 from stat(2) (so owner uid isn't known). Would it be okay to just elide that file from the glob's expansion? - Error out hard? NULL_GLOB is typically used to mean "Treat a glob with zero matches the same way as any other glob", and this case is rather "We couldn't determine the number of matches", so, maybe? - Enumerate all paths that compare case-insensitively equal to a different path and expand the glob as in the non-0711 case? Even assuming ASCII English this is O(2**N) in the length of the path (e.g., "test" is length 4 and has 2**4 possibilities), so, not tractable. Could be that I'm missing something, of course… Daniel
> On Aug 22, 2022, at 2:02 PM, Oliver Freyermuth <o.freyermuth@googlemail.com> wrote: > > I'm not sure if this is a bug or a feature — but I have seen some zsh scripts break when the top level home directory (/home) is set to mode 711 and owned by root > (as is common for shared home directories offered via network at our site), when nocaseglob is active. This behavior is known; see the discussions rooted at workers/47813 (https://www.zsh.org/mla/workers/2021/msg00026.html) and workers/47822 (https://www.zsh.org/mla/workers/2021/msg00035.html), and possibly others I'm not aware of. I don't remember if any of the proposed changes were accepted. -- vq
On Mon, Aug 22, 2022 at 1:15 PM Lawrence Velázquez <larryv@zsh.org> wrote:
>
> This behavior is known; see the discussions rooted at workers/47813
> (https://www.zsh.org/mla/workers/2021/msg00026.html) and workers/47822
> (https://www.zsh.org/mla/workers/2021/msg00035.html), and possibly
> others I'm not aware of. I don't remember if any of the proposed
> changes were accepted.
47913: implement CASE_PATHS option to make NO_CASE_GLOB more sensible
This was included in the 5.9 release.
The NEWS file says:
The option CASE_PATHS was added to control how NO_CASE_GLOB behaves.
NO_CASE_GLOB + NO_CASE_PATHS is equivalent to the current NO_CASE_GLOB
behaviour. NO_CASE_GLOB + CASE_PATHS treats only path components that
contain globbing characters as case-insensitive; this behaviour may
yield more predictable results on case-sensitive file systems.
NO_CASE_PATHS is the default.
Hi Bert,
Am 22.08.22 um 22:59 schrieb Bart Schaefer:
> On Mon, Aug 22, 2022 at 1:15 PM Lawrence Velázquez <larryv@zsh.org> wrote:
>>
>> This behavior is known; see the discussions rooted at workers/47813
>> (https://www.zsh.org/mla/workers/2021/msg00026.html) and workers/47822
>> (https://www.zsh.org/mla/workers/2021/msg00035.html), and possibly
>> others I'm not aware of. I don't remember if any of the proposed
>> changes were accepted.
>
> 47913: implement CASE_PATHS option to make NO_CASE_GLOB more sensible
>
> This was included in the 5.9 release.
>
> The NEWS file says:
>
> The option CASE_PATHS was added to control how NO_CASE_GLOB behaves.
> NO_CASE_GLOB + NO_CASE_PATHS is equivalent to the current NO_CASE_GLOB
> behaviour. NO_CASE_GLOB + CASE_PATHS treats only path components that
> contain globbing characters as case-insensitive; this behaviour may
> yield more predictable results on case-sensitive file systems.
> NO_CASE_PATHS is the default.
thanks! And also thanks to all others, I agree (after the examples outlined by Daniel) there is no simple way out, but a new option seems to be the most sensible approach.
Sadly, it does not seem to change the described case, using:
zsh --version
zsh 5.9 (x86_64-pc-linux-gnu)
I get:
1) Prepare directory:
mkdir foo
chmod 711 foo
mkdir foo/test
sudo chown root:root foo
cd foo/test
2) Test with caseglob:
setopt caseglob
echo $(pwd)(N)
=> Output is returned just fine.
3) Test with nocaseglob:
setopt nocaseglob
echo $(pwd)(N)
=> No output is returned (expected).
4) Test with nocaseglob and casepaths:
set nocaseglob
set casepaths
echo $(pwd)(N)
=> Also here, no output is returned. The path componend which can not be listed is "foo" which does not have any globbing characters inside.
I presume it fails since it still attempts to list the directory, which fails, before the actual matching is performed?
Cheers and thanks,
Oliver
On Mon, Aug 22, 2022 at 11:36:21PM +0200, Oliver Freyermuth wrote: > 4) Test with nocaseglob and casepaths: > set nocaseglob > set casepaths Shouldn't that be "setopt" or "set -o"? > echo $(pwd)(N) > > => Also here, no output is returned. The path componend which can not be listed is "foo" which does not have any globbing characters inside. > I presume it fails since it still attempts to list the directory, which fails, before the actual matching is performed? Ciao Dominik ^_^ ^_^ -- Dominik Vogt
Am 22.08.22 um 23:56 schrieb Dominik Vogt: > On Mon, Aug 22, 2022 at 11:36:21PM +0200, Oliver Freyermuth wrote: >> 4) Test with nocaseglob and casepaths: >> set nocaseglob >> set casepaths > > Shouldn't that be "setopt" or "set -o"? Indeed, my bad. And once I do that, it works as advertised... Many thanks to you all, that solves my issue :-). Ciao, Oliver > >> echo $(pwd)(N) >> >> => Also here, no output is returned. The path componend which can not be listed is "foo" which does not have any globbing characters inside. >> I presume it fails since it still attempts to list the directory, which fails, before the actual matching is performed? > > > Ciao > > Dominik ^_^ ^_^ > > -- > > Dominik Vogt >