如何让rm不删除符号链接?

问题描述 投票:0回答:3

所以,我正在删除不需要的文件,并删除了一些文件夹。一段时间后,我看到另一个文件夹在

ls -la
中显示为红色。我知道我删除了实际的文件夹,因此我非常伤心并尝试运行
foremost
来恢复,但运气不好。任何人都可以给我一些好的别名/函数来删除,例如 rm -rf 但如果该文件链接到其他文件,那么它不会删除。就像如果
/usr/bin/a.py
链接到
/root/a.py
并且我运行
rm -rf /usr/bin/a.py
那么
/root/a.py
将被删除。我怎样才能防止别名出现这种情况?

bash git terminal rm ln
3个回答
8
投票

Joe W 的答案是正确的,即

rm
通常不会删除符号链接的目标,但说它“不遵循符号链接”并不十分准确,至少在我的系统上(GNU coreutils 8.25)。而删除文件是一个非常重要的地方!让我们看一下它在几种情况下的表现。

如果您的符号链接是文件,而不是目录,则没有合理的方法可以使用

rm
意外删除目标。你必须做一些非常明确的事情,比如
rm "$(readlink file)"

但是,目录的符号链接有点危险,正如您不小心删除了一个目录时所看到的那样。这是我们可以使用的测试用例:

$ mkdir test1
$ touch test1/foo.txt
$ ln -s test1 test2
$ ls -lR
.:
total 4
drwxrwxr-x 2 soren soren 4096 Jun 29 17:02 test1
lrwxrwxrwx 1 soren soren    5 Jun 29 17:02 test2 -> test1

./test1:
total 0
-rw-rw-r-- 1 soren soren 0 Jun 29 17:02 foo.txt

这些都是安全的:

  • rm test2
    (仅删除符号链接)
  • rm -r test2
    (仅删除符号链接)
  • rm -rf test2
    (仅删除符号链接)
  • rm test2/
    rm: cannot remove 'test2/': Is a directory
    - 未采取任何行动)
  • rm -rf *2
    (或任何其他与符号链接匹配的 glob——仅删除符号链接)

这些安全:

  • rm -r test2/
    rm: cannot remove 'test2/': Not a directory
    - 但删除
    test1
    目录的内容)
  • rm -rf test2/
    (删除目录内容,保留符号链接,无错误)
  • rm -rf test2/*
    (删除目录内容,保留符号链接,无错误)

最后一个不安全的情况可能是明显的行为,至少对于熟悉 shell 的人来说是这样,但是前面的两个情况更加微妙和危险,特别是因为使用制表符补全

test2
的名称会删除尾随的字符为你斩杀!

有趣的是,

test
具有类似的行为,考虑到带有尾部斜杠的目录的符号链接不是符号链接而是目录,而没有尾部斜杠的符号链接是both

$ [ -L "test2" ] && echo "is link"
is link
$ [ -d "test2" ] && echo "is directory"
is directory
$ [ -L "test2/" ] && echo "is link"
$ [ -d "test2/" ] && echo "is directory"
is directory

这是“删除目录的符号链接而不删除目标”的先前的处理,对哪些有效、哪些无效进行了不太彻底的分析,但提供了一堆其他有用的信息。


不幸的是,我不知道有什么方法可以使用别名

rm
来防止这个错误。我想您可以编写一个函数来解析
rm
的参数,并警告您是否其中任何一个是以斜杠结尾的符号链接,如下所示:

function rm {
    for i in "$@"; do
        if [[ $i =~ /$ ]] && [ -L "${i:0:-1}" ]; then
            read -rp "Really delete symlink '$i' with trailing slash (y/n)? " result
            [ "$result" != "y" ] && return
        fi
    done
    command rm "$@"
}

不过,使用风险需您自担!它通过了 shellcheck,并且在我测试时它起作用了,但是在像

rm
这样基本且危险的东西之上实现一个包装器让我感到惶恐不安。

您可能在别名/函数中包含的其他两个可能有用的开关是

--one-file-system
(至少跳过符号链接之外的文件或安装到不同的驱动器上),如果您尚未使用它,则为
-i
 -I
在做有潜在危险的事情时进行提示。


1
投票

我不认为它的行为符合您的指示。 rm 不遵循符号链接

删除某些内容的唯一方法是执行类似

rm -rf myFolder/*
的操作,其中
myFolder
是链接目录。


0
投票

如果您想删除具有嵌套符号链接的目录树,并且您知道(或可以找出)它们在哪里,您可以首先使用

unlink
删除符号链接。

递归删除包含符号链接的目录树是危险的,特别是如果您使用 FTP,这也会导致链接目标的删除。 (我已经被这个困扰了,这就是我来这里的原因。我认为这是 Linux shell 中的一个主要错误。)

© www.soinside.com 2019 - 2024. All rights reserved.