必要性自不必说,实现的方式有多种。本帖只是想按照自己的思路写成脚本,放到$PATH里面。也许也可作纯技术讨论,如果能算作“技术”。
2、示例
简单的debug了几天,对于文件名不算太复杂的都应该可以处理。例如:
代码: 全选
aBiNg:~ ¶ mkdir -p zzz/zz/z
aBiNg:~ ¶ touch zzz/{a,a.mp3,b.mp3} zzz/zz/a
aBiNg:~ ¶ del zzz/*.mp3 ~/zzz/a /home/wujie/zzz/zz/a zzz/zz/z/
aBiNg:~ ¶ t
aBiNg:~/.Trash ¶ ll
total 4
-rw-r--r-- 1 wujie wujie 0 2008-02-25 17:29 home::wujie::zzz::a>>2008-02-25@17:30:55
-rw-r--r-- 1 wujie wujie 0 2008-02-25 17:29 home::wujie::zzz::zz::a>>2008-02-25@17:30:55
-rw-r--r-- 1 wujie wujie 0 2008-02-25 17:29 zzz::a.mp3>>2008-02-25@17:30:55
-rw-r--r-- 1 wujie wujie 0 2008-02-25 17:29 zzz::b.mp3>>2008-02-25@17:30:55
drwxr-xr-x 2 wujie wujie 4096 2008-02-25 17:28 zzz::zz::z>>2008-02-25@17:30:55
aBiNg:~/.Trash ¶ more .file_deleted_path
2008-02-25@17:30:55 -f /home/wujie/zzz/a.mp3
2008-02-25@17:30:55 -f /home/wujie/zzz/b.mp3
2008-02-25@17:30:55 -f /home/wujie/zzz/a
2008-02-25@17:30:55 -f /home/wujie/zzz/zz/a
2008-02-25@17:30:55 -d /home/wujie/zzz/zz/z
aBiNg:~/.Trash ¶ undel *
' /home/wujie/zzz/a ' has been recovered.
' /home/wujie/zzz/zz/a ' has been recovered.
' /home/wujie/zzz/a.mp3 ' has been recovered.
' /home/wujie/zzz/b.mp3 ' has been recovered.
' /home/wujie/zzz/zz/z ' has been recovered.
aBiNg:~/.Trash ¶ more .file_deleted_path
aBiNg:~/.Trash ¶ cd
aBiNg:~ ¶ ls -R zzz/
zzz/:
a a.mp3 b.mp3 zz
zzz/zz:
a z
zzz/zz/z:
从上面的输出大概也能看到点思路。
就是先将file的有关属性存放起来,修改,再加到"~/.Trash/.file_deleted_path"文件里面,形成一个档案备份,以利于'undel'命令的恢复文件;恢复之后,同时清空掉档案备份中的对应项即可。
因为实际执行的是mv,所以执行速度上无需多虑。想真正删除文件,rm即可。
获得与释放文件属性是本脚本的麻烦之处,用了许多字符处理的操作,所以我担心:当文件名很复杂(含有太多不常用字符)时,可能就不能胜任了,还请诸位不吝赐教。
4、内容
脚本内容:
代码: 全选
aBiNg:~/script ¶ more del undel
代码: 全选
::::::::::::::
del
::::::::::::::
#!/bin/bash
# the customized command 'del' used to replace 'rm' command
# written by [email protected]
# completed at 2008-02-24
current_dir=`pwd`
deltime=`date +%F@%T`
storage=~/.Trash/.file_deleted_path
delimiter='>>'
[ $current_dir == `dirname $storage` ] && \
echo "you should not run 'del' command in ~/.Trash directory!" && \
exit
[ ! -f $storage ] && touch $storage
for fname in "$@"
do
# erase backslashed '\' and last character if it's a slash '/'
tmp=`echo $fname | sed 's/\(.*\)\/$/\1/'`
base=`basename $tmp`
# finalepath/name check
if [ "${fname:0:1}" == '/' -o "${fname:0:1}" == '~' ]
then
finalpath=$tmp
finalname=`echo $tmp | sed 's!/!::!g' | sed 's!::!/!'`$delimiter$deltime
else
finalpath=$current_dir/$tmp
finalname=`echo $tmp | sed 's!/!::!g'`$delimiter$deltime
fi
[ -f $tmp ] && filetype='-f'
[ -d $tmp ] && filetype='-d'
[ x"" == x"$filetype" ] && \
echo "Error, ' $base 'does not exist!" && \
continue
# add deleted archive's profiles to $storage
echo "$deltime $filetype $finalpath" >> $storage
mv $finalpath ~/.Trash/$finalname
done
代码: 全选
::::::::::::::
undel
::::::::::::::
#!/bin/bash
# 'undel' used to recovery deleted files done by 'del'
# written by [email protected]
# completed at 2008-02-24
storage=~/.Trash/.file_deleted_path
[ `pwd` != `dirname $storage` ] && \
echo "you should run 'undel' command in ~/.Trash directory!" && \
exit
for delfname in "$@"
do
# erase backslashes '\' and last character if it's a slash '/'
tmpname=$(basename $(echo "$delfname"))
mn=$(($(echo "$tmpname" | grep "::" -o | wc -l)+1))
# get the file's realname and deleted time
corename=${tmpname%%>>*}
deltime=${tmpname##*>>}
realname=`echo "$corename" | sed 's!::!/!g'`
[ -f $tmpname ] && filetype="-f"
[ -d $tmpname ] && filetype="-d"
patharray=$(grep $deltime $storage | awk '$2=="'$filetype'" {print $3}')
# get sections of the undeleted file's corepath
for path in $patharray
do
for i in `seq $mn`
do
array[$i]=`echo "$path" | rev | cut -d '/' -f "$i" | rev`
cpath[1]=${array[1]}
[ $i -gt 1 ] && cpath[$i]=${array[$i]}/${cpath[$((i-1))]}
done
[ "${cpath[$mn]}" == "$realname" ] && fpath=$path && \
break
done
[ x"$fpath" == x"" ] && \
echo "cann't find the path of ' $tmpname ', nothing done!" && \
continue
# update $storage file
ml=$(cat -n $storage | sed -ne "/$deltime/{/$filetype/p}" | \
awk '$4=="'$fpath'" {print $1}')
sed "$ml d" $storage > /tmp/storage.new
mv /tmp/storage.new $storage
# finish the job <-- replace 'rm' by 'mv'
dirpath=`dirname $fpath`
[ ! -d $dirpath ] && mkdir -p $dirpath
if [ ! -f $fpath ]
then
mv $delfname $fpath && \
echo "' $fpath ' has been recovered."
else
echo "' $fpath ' exists, nothing done!"
fi
done