Zsh Mailing List Archive
Messages sorted by:
Re: glob qualifier '-' doesn't work correctly on dangling symlinks
2020-04-12 04:17:22 +0200, Vincent Lefevre:
> > What would be the glob qualifier syntax for broken symlinks?
> There would need something for that. But even currently, there
> are things one cannot do with glob qualifiers, such as one does
> not have a way to know the reason why a symlink is broken, which
> can be important when one is interested in broken symlinks.
> zira% ln -s /does-not-exist s1
> zira% ln -s /root/foo s2
> zira% ls -L s*
> ls: cannot access 's1': No such file or directory
> ls: cannot access 's2': Permission denied
> But with glob qualifiers, there does not seem to be a way to
> distinguish these two cases.
$ zmodload zsh/system
$ ls -ld -- *(e[ERRNO=0]-e['[[ $errnos[ERRNO] = EACCES ]]'])
lrwxrwxrwx 1 chazelas chazelas 9 Apr 12 07:34 s2 -> /root/foo
$ ls -ld -- *(e[ERRNO=0]-e['[[ $errnos[ERRNO] = ENOENT ]]'])
lrwxrwxrwx 1 chazelas chazelas 15 Apr 12 07:34 s1 -> /does-not-exist
(the ERRNO=0 may not be necessary).
$ find -L . -perm -o=w
find: ‘./s2’: Permission denied
But again, *(-@) for broken symlinks is documented and widely
used, we can't break that.
So if we change "-" to exclude broken symlinks, we'd need to
special case -@. What's the scope of what should be special
cased? *(-@e['((count++))']) should probably still work as well
How about: *(-e['((n++))']@['((brokenlinks++))'])?
And *(-@m-1) (broken links created in the last 24 hours, though
I'd expect one to write *(m-1-@) instead here)
Note that for "find -L", zsh's current behaviour is required by
POSIX (at least for links whose target can be determined not to
Cause the file information and file type evaluated for
each symbolic link encountered as a path operand on
the command line or encountered during the traversal
of a file hierarchy to be those of the file referenced
by the link, and not the link itself. If the
referenced file does not exist, the file information
and type shall be for the link itself.
I find some variation in behaviour though:
$ ln -s /etc/passwd/foo s3
$ gfind . -follow -perm -o=w
gfind: ‘./s3’: Not a directory
gfind: ‘./s2’: Permission denied
$ busybox find . -follow -perm -o=w
find: ./s3: Not a directory
find: ./s2: Permission denied
$ find_su3 . -follow -perm -o=w
find_su3: cannot follow symbolic link ./s3: Not a directory
find_su3: cannot follow symbolic link ./s1: No such file or directory
find_su3: cannot follow symbolic link ./s2: Permission denied
(the latter from the heirloom toolchest being not POSIX compliant)
In any case, in */*(W), or ***/*(W) or **/*(W), the cases where
directories are not readable or searchable, or symlink targets
not accessible are always silently ignored (as opposed to the
Messages sorted by: