如何让rm不删除符号链接?
How to make rm not delete symbolic links?
因此,我删除了不需要的文件并删除了一些文件夹。一段时间后,我看到另一个文件夹在 ls -la
中显示为红色。我知道我删除了实际的文件夹,因此我非常难过并试图 运行 foremost
恢复但运气不好。任何人都可以给我一些像 rm -rf 一样删除的好 aliases/function 但是如果该文件链接到其他文件则它不会删除。就像 /usr/bin/a.py
链接到 /root/a.py
而我 运行 rm -rf /usr/bin/a.py
那么 /root/a.py
将被删除。我怎样才能避免使用别名?
我不认为它的行为方式与您指示的方式相同。 rm 不遵循符号链接
- https://superuser.com/questions/520058/does-rm-r-follow-symbolic-links
- https://superuser.com/questions/382314/does-rm-rf-follow-symbolic-links
您可以删除某些内容的唯一方法是执行类似 rm -rf myFolder/*
的操作,其中 myFolder
是一个链接目录。
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
有类似的行为,考虑到带有尾部斜杠的目录的符号链接不是符号链接而是目录,而没有尾部斜杠的符号链接是 两者:
$ [ -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
这里有一个 previous treatment 的“删除目录的符号链接而不删除目标”,对到底什么有效什么无效的分析不太透彻,但提供了一些其他有用的信息。
不幸的是,我不知道有什么方法可以使用别名 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 "$@"
}
不过,使用风险自负!它通过了 shell 检查并且在我测试它时它起作用了,但是在像 rm
这样基本和危险的东西之上实现一个包装器让我很高兴。
您可能在 alias/function 中包含的其他两个可能有用的开关是 --one-file-system
(至少跳过符号链接后的文件或装载到不同的驱动器上),如果您还没有使用它,-i
或 -I
在做有潜在危险的事情时进行提示。
因此,我删除了不需要的文件并删除了一些文件夹。一段时间后,我看到另一个文件夹在 ls -la
中显示为红色。我知道我删除了实际的文件夹,因此我非常难过并试图 运行 foremost
恢复但运气不好。任何人都可以给我一些像 rm -rf 一样删除的好 aliases/function 但是如果该文件链接到其他文件则它不会删除。就像 /usr/bin/a.py
链接到 /root/a.py
而我 运行 rm -rf /usr/bin/a.py
那么 /root/a.py
将被删除。我怎样才能避免使用别名?
我不认为它的行为方式与您指示的方式相同。 rm 不遵循符号链接
- https://superuser.com/questions/520058/does-rm-r-follow-symbolic-links
- https://superuser.com/questions/382314/does-rm-rf-follow-symbolic-links
您可以删除某些内容的唯一方法是执行类似 rm -rf myFolder/*
的操作,其中 myFolder
是一个链接目录。
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
有类似的行为,考虑到带有尾部斜杠的目录的符号链接不是符号链接而是目录,而没有尾部斜杠的符号链接是 两者:
$ [ -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
这里有一个 previous treatment 的“删除目录的符号链接而不删除目标”,对到底什么有效什么无效的分析不太透彻,但提供了一些其他有用的信息。
不幸的是,我不知道有什么方法可以使用别名 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 "$@"
}
不过,使用风险自负!它通过了 shell 检查并且在我测试它时它起作用了,但是在像 rm
这样基本和危险的东西之上实现一个包装器让我很高兴。
您可能在 alias/function 中包含的其他两个可能有用的开关是 --one-file-system
(至少跳过符号链接后的文件或装载到不同的驱动器上),如果您还没有使用它,-i
或 -I
在做有潜在危险的事情时进行提示。