删除文件,但仅当它是符号链接时


11

理想情况下,我想要这样的命令

rm --only-if-symlink link-to-file

因为我烧掉自己太多次了,所以不小心删除了文件而不是指向文件的符号链接。当涉及到sudo时,这尤其糟糕。现在,我当然要做一个a ls -al,以确保它确实是一个符号链接,但是这样很容易受到操作员错误(类似文件,错字等)和竞争条件(如果有人出于某种原因要我删除文件)的攻击。有什么方法可以检查文件是否为符号链接,并且仅在一个命令中才将其删除?


1
我认为比赛条件不应该成为问题。任何能够删除符号链接并将其替换为文件的人都需要对该目录具有写权限,这意味着他们也可以自己删除该文件。
Nate Eldredge

Answers:


19
 $ rm_if_link(){ [ ! -L "$1" ] || rm -v "$1"; }

 #test
 $ touch nonlink; ln -s link
 $ rm_if_link nonlink
 $ rm_if_link link
   removed 'link'     

4
当然,将其删除!并更改||为更为清晰&&
glenn jackman

5
@glennjackman我已经习惯了使用||表单。&&如果您处于set -e模式下,会降低一切。
PSkocik

@PSkocik这通常是有风险的,因为它无法区分使用有趣的情况(文件存在并且是符号链接)和其他非零退出代码的原因,例如[ ! -L $1 ]使用无效运算符(的空未引用值(),[ ! -l foo ]),甚至语法错误([ ! -q foo || echo foo
l0b0

2
@XiongChiamiov的问题rm_if_link(){ [ -L "$1" ] && rm -v "$1"; }是,在非链接set -e 模式下运行它会杀死您的Shell进程。您可以追加,|| :但是它变得恕我直言,甚至比! ||版本还不清晰,并且可以防止rm失败杀死您set -e,这可能是不希望的。! ||非常简洁明了,不会遇到任何这些问题。
PSkocik

1
都能跟得上。其他选项:a)rm在测试中放入内部,b)使用实际的if语句,c)不要-e在交互式外壳内部使用(测试脚本!)。如果您想讨论可读性,那么使用if测试来确定某事物是否是链接显然是赢家。
Monica Cellio的抵制SE

5

可以使用find和它的-type l测试条件(在此进行测试以查看是否该对象发现是一个油墨与否)

例如,如果您foo在当前目录中有一个名为的文件,则可以这样做:

$ find . -type l -iname "foo" -delete

您也许可以通过以下方式简化它:

$ find . -maxdepth 1 -type l -delete

这将删除当前目录中的所有符号链接。

警告:

这个-delete选项find真的很危险。确保将其放置在查找命令的末尾。如果放错了位置,它将删除找到的所有内容,而不管结果是否符合条件。

如评论中所建议,更安全的选择可能是使用findrm -i(强制您确认文件删除)结合使用:

$ $ find . -type l -iname "foo" | xargs rm -i

就我个人而言,我曾经-exec trash {} \;临时删除文件,因为我和您一样,rm过去曾经被烧死。Double将放错位置的-delete标志。

http://slackermedia.ml/trashy


1
代替-delete,您可以打印它并将其传递给xargs:find . -type l -iname "foo" | xargs rm -i 这更安全。
Boban P.

1
当然,我喜欢@BobanP。rm -i对安全的使用。
Klaatu von Schlacker

3
“这将删除当前目录中的所有符号链接”……及其下面的任何点。
Joseph R.

1
作为@JosephR。说,它将一路走下去。在查找中添加-maxdepth 1。
Boban P.

1
仍然在文件名上带有空格的地方中断。建议使用-print0for find-0for xargs
通配符

4
zsh -c 'rm foo(@)'

@全局限定词 ; 模式foo(@)与匹配项foo匹配,但仅符号链接匹配。

foo(-@)只会匹配断开的符号链接。foo(@,L0)将仅匹配符号链接和空文件。

当然,如果首先运行zsh,则只需键入rm foo(@)。您确实需要注意不要Enter在键入前按任何键(@)


1
当我看到这样的答案时,Zsh的声音越来越强大。
杰夫·谢勒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.