Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
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.
[...]
There's:
$ 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).
Note:
$ find -L . -perm -o=w
./s1
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
for instance.
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
exist):
-L
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
./s3
./s1
gfind: ‘./s2’: Permission denied
$ busybox find . -follow -perm -o=w
find: ./s3: Not a directory
./s1
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
find equivalents).
--
Stephane
Messages sorted by:
Reverse Date,
Date,
Thread,
Author