当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 5 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : del 替代 rm 的自用脚本
帖子发表于 : 2008-02-25 17:54 

注册: 2006-07-09 12:22
帖子: 1331
地址: 南京
送出感谢: 0 次
接收感谢: 1
1、引言
必要性自不必说,实现的方式有多种。本帖只是想按照自己的思路写成脚本,放到$PATH里面。也许也可作纯技术讨论,如果能算作“技术”。:wink:

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:


3、思路
从上面的输出大概也能看到点思路。

就是先将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 abing@yahoo.cn
# 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 abing@yahoo.cn
# 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


页首
 用户资料  
 
2 楼 
 文章标题 :
帖子发表于 : 2008-02-25 23:45 

注册: 2007-11-27 22:20
帖子: 444
送出感谢: 0 次
接收感谢: 0 次
学习shell中


页首
 用户资料  
 
3 楼 
 文章标题 :
帖子发表于 : 2008-02-26 0:42 
头像

注册: 2007-11-19 21:51
帖子: 6956
地址: 成都
送出感谢: 0 次
接收感谢: 4
lz的意思是类似回收站的还原功能吗?貌似最新的gnome支持回收站还原了呢


页首
 用户资料  
 
4 楼 
 文章标题 :
帖子发表于 : 2008-02-26 9:48 

注册: 2006-07-09 12:22
帖子: 1331
地址: 南京
送出感谢: 0 次
接收感谢: 1
xiooli
嗯,是还原的意思。但是命令行操作的,不是nautilus(你指gnome中默认的这个吧?)。

rm 命令与gnome无关啊,而我自己不用gnome,呵呵。

对于常在shell中管理系统的,可能有点用途吧。


页首
 用户资料  
 
5 楼 
 文章标题 :
帖子发表于 : 2008-02-26 13:50 
头像

注册: 2007-11-19 21:51
帖子: 6956
地址: 成都
送出感谢: 0 次
接收感谢: 4
aBiNg 写道:
xiooli
嗯,是还原的意思。但是命令行操作的,不是nautilus(你指gnome中默认的这个吧?)。

rm 命令与gnome无关啊,而我自己不用gnome,呵呵。

对于常在shell中管理系统的,可能有点用途吧。

如果是命令行的话,确实挺有用


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 5 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译