您好,我正在创建一个名为“safe_rm”的回收站脚本。我想知道,如何防止脚本删除自己的文件。我相信 readlink 命令是一种解决方案,但我不确定如何在脚本中编写它。
这是我当前的代码
while [ $# -ne 0 ]
do
if [ ! -e "$1" ] ; then
echo "File not found."
elif [ -d "$1" ] ; then
echo "Error. You have entered a directory."
elif [ $1 = $(readlink -e ~/project/safe_rm) ] ;
echo "Attempting to delete safe_rm - operation aborted"
exit 0
else
inode=` ls -i $1 | cut -d" " -f1 `
echo $1_$inode:$(readlink -e $1) >> /home/j.t/.restore.info
mv $1 /home/j.t/deleted/$1_$inode
echo "File '$1' has been moved to the recycle bin."
fi
shift
done
需要修改的代码在第8行。
答案1
您距离可行的解决方案仅差一步。规范化变量,就完成了:
elif [ "$(readlink -e "$1")" = "$(readlink -e ~/project/safe_rm)" ] ;
我将所有内容都用引号引起来,因为路径可能包含空格。请注意,您不必转义 subshell ( $(…)
thingy) 内的引号。感谢@glenn jackman 的更正。
答案2
如果您使用的readlink -e
是 GNU coreutils。但使用ls
来获取inode值是间接的。通过使用stat
(也来自同一个 coreutils 包),您可以直接获取 inode 值。如果您限制与 inode 的比较,您还可以防止删除可能已设置为指向脚本的符号链接。
这是一个例子:
#!/bin/sh
mynode=$(stat --printf='%i' $(readlink -e "$0"))
while [ $# -ne 0 ]
do
if [ ! -e "$1" ] ; then
echo "File not found."
elif [ -d "$1" ] ; then
echo "Error. You have entered a directory."
else
itnode=$(stat --printf='%i' "$1")
if [ $mynode = $itnode ] ; then
echo "Attempting to delete $0 - operation aborted"
exit 0
fi
echo "$1_$itnode:$(readlink -e "$1")" >> /home/j.t/.restore.info
mv "$1" "/home/j.t/deleted/$1_$itnode"
echo "File '$1' has been moved to the recycle bin."
fi
shift
done
答案3
chattr 可以禁止除 root 之外的任何人删除文件,甚至是存储在垃圾箱中的文件。
作为根用户
chattr +i /path/to/safe_rm