2014-02-28 45 views
26

对于给定的文件夹,如何删除其中的所有损坏的链接?用线删除所有断开的符号链接?

我发现this answer显示如何删除一个断开的链接,但我不能只将它们放在一行中。有没有一个这样的班轮?

断开的符号是指向不再存在的文件/文件夹的链接。

+0

直接从“man find”查找:'find -L/usr/ports/packages -type l -exec rm - {} + 删除/ usr/ports/packages中的所有破碎的符号链接。 –

回答

50

下面是删除当前目录下的所有破损符号链接的POSIX方式,没有递归。它的工作原理是告诉find遍历符号链接(-L),但在每个目录或符号链接处停止(-prune)。

find -L . -name . -o -type d -prune -o -type l -exec rm {} + 

您还可以使用shell循环。测试-L匹配符号链接,并且-e匹配现有文件(不包括损坏的符号链接)。

for x in * .[!.]* ..?*; do if [ -L "$x" ] && ! [ -e "$x" ]; then rm -- "$x"; fi; done 

如果你想递归到子目录,这种技术是行不通的。使用GNU查找(可在非嵌入式Linux和Cygwin上找到),可以使用-xtype谓词来检测断开的符号链接(-xtype使用符号链接的目标类型,并且报告链接断开时报告l)。 POSIXly,你需要结合两个工具。您可以使用find -type l -exec …在每个符号链接上调用命令,并使用[ -e "$x" ]来测试该链接是否未损坏。

find . -type l -exec sh -c 'for x; do [ -e "$x" ] || rm "$x"; done' _ {} + 

最简单的解决方案是使用zsh。要删除当前目录下的所有破损符号链接:

rm -- *([email protected]) 

括号中的字符是glob qualifiers-取消引用符号链接,@只匹配符号链接(组合[email protected]意味着只有破碎的符号链接),并D匹配点文件。为了递归到子目录中,使其成为rm -- **/*([email protected])

find -L $DIR -maxdepth 1 -type l -delete 
+1

对于真正酷酷的zsh示例+1,以及整体答案。但同样的问题:为什么'rm'而不是'unlink'?是不是有'rm'不安全的情况? – fotanus

+0

@fotanus呃? 'rm'有什么问题? – Gilles

+0

我不知道,我只是问,因为我的试验使用'unlink'代替。我不知道为什么。也许是因为它是一个链接? :P无论如何,这是另一个问题 – fotanus

0

您可以使用readlink来确定符号链接是否损坏。

下面将列出在一个给定的目录中的所有符号链接破碎(和子目录):

find . -type l -exec sh -c 'readlink -f "{}" 1>/dev/null || echo "{}"' -- "{}" \; 

更换echorm摆脱破的了!

(我重定向的readlink输出到/dev/null,以避免混乱,它会列出目标的符号链接。)

+0

By you nickname ,我看你喜欢重定向到/ dev/null :-)谢谢,'unlink'呢? – fotanus

+0

@fotanus为什么'unlink','rm'有什么问题? – devnull

+0

@fotanus顺便说一句,如上所述,在这种情况下重定向到'/ dev/null'纯粹是为了避免混淆。即使你不这样做,并用'rm'替换echo,它也不会造成任何副作用。 – devnull

15

答案很简单:

find -L /usr/ports/packages -type l -exec rm -- {} + 

Delete all broken symbolic links in /usr/ports/packages.

+3

我喜欢这个最好的。即使查找手册页似乎意味着这是一个寻找破碎的符号链接的解决方案。 –

+2

在Mac OS上(BSD'find'),@ sanmiguel的命令给出错误:'find:-delete:禁止符号链接时禁止' – Diti

+0

@Diti:请参阅https://stackoverflow.com/a/45233047/1874627 – saurabheights

3

man find举例根据您链接(对于给定的目录,$DIR)答案

1

symlinks是预装在许多发行版(包括Ubuntu 16.04 &的Fedora 25),并有一些非常有用的功能,其中一个不正是你要寻找的:

symlinks -d ./ 
+0

symlinks没有预装在CentOS 7.3或Ubuntu 14上.Ubuntu 16有内核4.10,它有这个问题:https://groups.google.com/forum/#!topic/linux.kernel/C1Uk5cnrPgs。当然,如果你没有运行SSL服务器,那么Ubuntu 16可能没问题。 –

0

对于MAC,做一个预演如下: -

DIR=<some path> 
find -L $DIR -maxdepth 1 -type l -print 

现在,你可以修剪旧符号链接如下: -

for f in `find -L $DIR -maxdepth 1 -type l`; do unlink $f; done 
0

您可以尝试使用rmlint

首先,改变目录到包含破碎的符号链接,然后 运行以下命令找到坏的符号链接指向无处文件夹:

rmlint --types="badlinks" 

然后rmlint将在当前创建一个bash脚本rmlint.sh目录并在您的终端中打印错误符号链接列表。要删除当前目录中所有错误的符号链接,您可以运行

./rmlint.sh 

不完全是一个班轮,但它非常易于使用。