find -type l
并ls -l | grep '^l'
显示符号链接,但不区分指向目录的符号链接和指向文件的符号链接。做这样的事情的一种非常笨拙的方法是,find -type l -exec file -L '{}' ';' | grep directory
但效率非常低。
有没有更好的方法来仅查找指向目录的符号链接?
答案1
根据的 POSIX 规范test
,-d
测试为:
为真,如果路径名解析为目录的现有目录条目。
因此,一旦有了符号链接,就可以使用[ -d ... ]
它:
find . -type l -exec test -d {} \; -print
或者,避免为每个链接执行外部命令:
find . -type l -exec sh -c 'for l; do [ -d "$l" ] && printf "%s\n" "$l"; done' _ {} +
答案2
您可以-type l
与 一起使用-xtype d
。 (不过我不知道是否-xtype
是 POSIX。)
答案3
为了桀骜用户,这可以很容易地实现使用全局限定符 (@-/)
:
for F in **/*(N@-/); do the_thing "$F"; done
分解该表达式:**/*
glob 递归地匹配所有文件/目录,不包括隐藏的文件/目录。(expr)
在 glob 将匹配限制为满足特定条件的文件之后。这里的标准是:
N
:在该扩展中启用 nullglob,这样如果没有匹配的文件,它就会扩展为空而不是导致错误。当在for
循环或数组赋值中使用 glob 时,通常需要使用该限定符。@
: 只匹配符号链接-
:从测试链接本身切换到测试链接目标/
: 只匹配目录
示例输出,在我的系统上运行/etc/
:
% ls -ldF -- **/*(@-/)
lrwxrwxrwx 1 root root 46 Sep 22 2022 alternatives/desktop-plasma5-wallpaper -> /usr/share/desktop-base/active-theme/wallpaper/
lrwxrwxrwx 1 root root 39 Sep 22 2022 alternatives/desktop-theme -> /usr/share/desktop-base/homeworld-theme/
lrwxrwxrwx 1 root root 36 Sep 22 2022 alternatives/vendor-logos -> /usr/share/desktop-base/debian-logos/
lrwxrwxrwx 1 root root 11 Sep 22 2022 runit/runsvdir/default/ssh -> /etc/sv/ssh/
lrwxrwxrwx 1 root root 18 Aug 7 2022 xdg/systemd/user -> ../../systemd/user/
请注意,这也匹配指向指向目录的链接的链接,而不仅仅是直接链接。
答案4
这是我的版本,应该比find . -type l -exec test -d {} \; -print
许多链接更有效:
$ find / -type l -print0 |
xargs -0 stat -L -c'%F %n' |
awk '$1 == "directory" { print substr($0, 11) }'
它找到所有链接,将它们输入stat
以确定文件类型,然后awk
过滤目录,只留下文件名。
如果没有awk
你得到类似的东西:
directory /sys/module/libnvdimm/holders/nfit
确认:
$ ll /sys/module/libnvdimm/holders/nfit
lrwxrwxrwx 1 root root 0 Oct 20 13:49 /sys/module/libnvdimm/holders/nfit -> ../../nfit
$ readlink -f /sys/module/libnvdimm/holders/nfit
/sys/module/nfit
$ ll -d /sys/module/nfit
drwxr-xr-x 6 root root 0 Oct 16 20:45 /sys/module/nfit