删除文件,但前提是它是符号链接

She*_*acu 14 command-line bash rm

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

rm --only-if-symlink link-to-file
Run Code Online (Sandbox Code Playgroud)

因为我已经烧了自己太多次不小心删除了文件而不是指向文件的符号链接。当涉及 sudo 时,这可能特别糟糕。现在我当然会做一个ls -al以确保它确实是一个符号链接等,但这很容易受到操作员错误(类似命名的文件、拼写错误等)和竞争条件(如果有人出于某种原因希望我删除文件)的影响。有没有办法检查文件是否是符号链接,并且只有在一个命令中才删除它?

PSk*_*cik 21

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

 #test
 $ touch nonlink; ln -s link
 $ rm_if_link nonlink
 $ rm_if_link link
   removed 'link'     
Run Code Online (Sandbox Code Playgroud)

  • 当然,删除 `!` 并将 `||` 更改为 `&&` 会更清楚 (5认同)
  • @glennjackman 我已经养成了喜欢 `||` 形式的习惯。如果你处于 `set -e` 模式,`&&` 会把事情搞砸。 (5认同)
  • @XiongChiamiov `rm_if_link(){ [ -L "$1" ] && rm -v "$1"; 的问题;}`是在`set -e`模式下在非链接上运行它会杀死你的shell进程。你可以附加`|| :` 但后来它变得,恕我直言,甚至比 `! ||` 版本,它会防止 `rm` 失败在 `set -e` 中杀死你,这可能是不受欢迎的。`!||` 非常简洁明了,不会遇到任何这些问题。 (2认同)

Kla*_*ker 6

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

例如,如果您foo在当前目录中调用了一个文件,您可以这样做:

$ find . -type l -iname "foo" -delete
Run Code Online (Sandbox Code Playgroud)

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

$ find . -maxdepth 1 -type l -delete
Run Code Online (Sandbox Code Playgroud)

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

警告:

-deletein的选项find真的很危险。请务必将其放在 Find 命令的末尾。如果您放错了位置,无论结果是否符合您的条件,它都会删除它找到的所有内容。

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

$ $ find . -type l -iname "foo" | xargs rm -i
Run Code Online (Sandbox Code Playgroud)

我个人习惯-exec trash {} \;临时删除文件,因为我和你一样,rm过去也被烧毁了。Double 代表错位的-delete标志。

http://slackermedia.ml/trashy

  • “这将删除当前目录中的所有符号链接”......以及它下面的任何点。 (3认同)

Gil*_*il' 5

zsh -c 'rm foo(@)'
Run Code Online (Sandbox Code Playgroud)

@是一个全局限定符;模式foo(@)匹配foo匹配的内容,但仅匹配符号链接。

foo(-@)只会匹配损坏的符号链接。foo(@,L0)只匹配符号链接和空文件。

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