こんにちは。 「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
実行可能なソリューションは今1段階残っています。変数を正規化すると完了です。
elif [ "$(readlink -e "$1")" = "$(readlink -e ~/project/safe_rm)" ] ;
パスにスペースが含まれる可能性があるため、すべての項目を引用符で囲みました。$(…)
サブシェルの内部では、引用符をエスケープする必要はありません。修正してくれた@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は、ルート以外の誰でもファイル、ゴミ箱に保存されているファイルを削除するのを防ぎます。
rootユーザーとして
chattr +i /path/to/safe_rm