Bash 如何使rm不删除符号链接?

Bash 如何使rm不删除符号链接?,bash,git,terminal,rm,ln,Bash,Git,Terminal,Rm,Ln,所以,我正在清除不需要的文件,并删除了一些文件夹。过了一段时间,我看到另一个文件夹在ls-la中显示为红色。我知道我删除了实际的文件夹,因此我很难过,并试图运行最前面的恢复,但运气不好。谁能给我一些好的别名/函数,像rm-rf一样删除,但如果该文件链接到其他文件,它就不会删除。例如,如果/usr/bin/a.py链接到/root/a.py,并且我运行rm-rf/usr/bin/a.py,那么/root/a.py将被删除。如何防止别名出现这种情况?我不认为它的行为与您所指示的方式相同。rm不遵循符

所以,我正在清除不需要的文件,并删除了一些文件夹。过了一段时间,我看到另一个文件夹在ls-la中显示为红色。我知道我删除了实际的文件夹,因此我很难过,并试图运行最前面的恢复,但运气不好。谁能给我一些好的别名/函数,像rm-rf一样删除,但如果该文件链接到其他文件,它就不会删除。例如,如果/usr/bin/a.py链接到/root/a.py,并且我运行rm-rf/usr/bin/a.py,那么/root/a.py将被删除。如何防止别名出现这种情况?

我不认为它的行为与您所指示的方式相同。rm不遵循符号链接


唯一可以删除某些内容的方法是执行类似于rm-rf myFolder/*的操作,其中myFolder是一个链接目录。

我认为它的行为与您指示的方式不同。rm不遵循符号链接


您可以删除某些内容的唯一方法是执行类似rm-rf myFolder/*的操作,其中myFolder是一个链接目录。

Joe W的回答是正确的,他说rm通常不删除符号链接的目标,但说它不遵循符号链接并不十分准确,至少在我的系统GNU coreutils 8.25上是如此。删除文件是一个准确性非常重要的地方!让我们来看看它在一些情况下的行为。

如果您的符号链接是指向一个文件,而不是指向一个目录,那么使用rm无法意外删除目标。您必须执行一些非常明确的操作,如rm$readlink文件

然而,指向目录的符号链接有点冒险,正如您意外删除一个目录时所看到的。下面是一个我们可以使用的测试用例:

$ 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:无法删除“test2/”:是一个目录-未执行任何操作 rm-rf*2或与符号链接匹配的任何其他glob-仅删除符号链接 这些是不安全的:

rm-r test2/rm:无法删除“test2/”:不是目录-而是删除test1目录的内容 rm-rf test2/删除目录的内容,保留符号链接,无错误 rm-rf test2/*删除目录内容,保留符号链接,无错误 最后一个不安全案例可能是显而易见的行为,至少对熟悉shell的人来说是如此,但之前的两个案例则更加微妙和危险,特别是因为完成test2名称的选项卡将为您插入尾部斜杠

有趣的是,注意到测试具有类似的行为,考虑到指向带有尾随斜杠的目录的符号链接不是符号链接而是目录,而不带尾随斜杠的符号链接是:

下面是一个在不删除目标的情况下删除指向目录的符号链接的示例,它不太透彻地分析了哪些是有效的,哪些是无效的,但使用了大量其他有用的信息

不幸的是,我不知道有什么方法可以别名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这样的基础和危险的东西上实现一个包装器给了我很大的麻烦


别名/函数中可能包含的另外两个可能有用的开关是-一个文件系统至少会跳过符号链接或将文件装载到不同的驱动器上,如果您尚未使用它,-i或-i在执行潜在危险的操作时提示。

Joe W的回答是正确的,他说rm通常不会删除符号链接的目标,但说它不遵循符号链接并不十分准确,至少在我的系统GNU coreutils 8.25上是如此。删除文件是一个准确性非常重要的地方!让我们来看看它在一些情况下的行为。

如果您的符号链接是指向一个文件,而不是指向一个目录,那么使用rm无法意外删除目标。您必须执行一些非常明确的操作,如rm$readlink文件

然而,指向目录的符号链接有点冒险,正如您意外删除一个目录时所看到的。下面是一个我们可以使用的测试用例:

$ 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:无法删除“test2/”:是一个目录-未执行任何操作 rm-rf*2或与符号链接匹配的任何其他glob-仅删除符号链接 这些是不安全的:

rm-r test2/rm:无法删除“test2/”:不是目录-而是删除test1目录的内容 rm-rf test2/删除目录的内容,保留符号链接,无错误 rm-rf test2/*删除目录内容,保留符号链接,无错误 最后一个不安全案例可能是显而易见的行为,至少对某些人来说是这样 e非常熟悉shell,但它之前的两个更微妙、更危险,特别是因为完成test2名称的tab会为您删除后面的斜杠

有趣的是,注意到测试具有类似的行为,考虑到指向带有尾随斜杠的目录的符号链接不是符号链接而是目录,而不带尾随斜杠的符号链接是:

下面是一个在不删除目标的情况下删除指向目录的符号链接的示例,它不太透彻地分析了哪些是有效的,哪些是无效的,但使用了大量其他有用的信息

不幸的是,我不知道有什么方法可以别名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这样的基础和危险的东西上实现一个包装器给了我很大的麻烦


别名/函数中可能包含的另外两个可能有用的开关是-一个文件系统至少会跳过符号链接或将文件装载到不同的驱动器上,如果您尚未使用它,-i或-i在执行可能有危险的操作时提示。

有两个文件夹,因此我删除了垃圾邮件,其中一个被删除:@DipsehSunrait:删除符号链接只会删除链接,而不会删除链接所链接的文件,至少只要你不使用-r。有两个文件夹,所以我删除了一个,但另一个被删除:@DipsehSunrait:删除符号链接只会删除链接,而不是它链接到的文件,至少只要你不使用-r。