안녕하세요. "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)" ] ;
경로에 공백이 포함될 수 있으므로 모든 항목을 따옴표로 묶었습니다. $(…)
서브셸(thingy) 내부에서는 따옴표를 이스케이프 처리할 필요가 없습니다 . 수정해주신 @glenn jackman에게 감사드립니다.
답변2
GNU coreutils를 사용하는 경우 readlink -e
. 그러나 이를 사용하여 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은 루트를 제외한 누구도 파일, 심지어 휴지통에 저장된 파일을 삭제하는 것을 방지할 수 있습니다.
루트 사용자로
chattr +i /path/to/safe_rm