免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6344 | 回复: 11
打印 上一主题 下一主题

[原创]自己设计的一个回收站(bash版) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-08-15 02:12 |只看该作者 |倒序浏览
由于以前自己曾经因为失误删了一些很重要的文件,而我们知道rm以后就没有挽回的余地了,所以自己就想过看能不能在终端也有一个回收站的功能就好了,这些天抽空写了一个自己的回收站,呵呵,不过功能不大,能实现基本的删除功能,查看回收站文件列表,从回收站里边恢复文件等一些功能,当然这个以后是要完善一下的。
    终端上实现回收站别人应该也做过,不过我不知道别人是怎么的一个做法,我是按照自己的想法做的,虽然功能也能实现,但不知道是不是一个很好的方法。
    好吧,首先向大家介绍一下我这个回收站实现的基本过程。这个回收站的命令我想了很久,后来决定叫做“trsh“,这是trash的缩写,也便于大家记忆嘛。而这个命令带不同的参数就可以实现不同的功能了。好了现在开始删除第一个文件吧。
   
   (一)首先假设我们的用户名叫linuxman,当前目录在/home/linuxman/trashtest/,这里有个文件aa.txt,那毫不犹豫删除它吧,trsh -m aa.txt (m选项表示删除文件的意思,本来想用d(elete)表示删除的,但那样会不会让别人觉得这个文件真的删除了呢,所以后来改用m(ove)选项),ls 看看,恩,aa.txt文件没了,那它到哪里去了呢,肯定不会是真的删除了的,不然我们这个回收站就失效了。现在用ls -a看看,怎么样?看到一个隐藏文件.trash_aa.txt,恩,这就是回收站实现的核心思想了。大家回忆一下windows里边的回收站,当你在某个盘里边删除里一个文件后,在没清除回收站之前,这个盘里的空间是不是还有部分是那个文件占据着的?那这个.trash_aa.txt 是不是就这样扔在那里不管了呢?当然不是,因为我们后面还是要恢复它的嘛。那又采取一个怎么样的方式来记录这个信息呢?我的做法就是删除文件之前把文件的一些信息,包括权限,属组,绝对路径等信息包存在用户根目录的一个隐藏文件.trashinfo.txt里边,比如这里的 /home/linuxman/.trashinfo.txt。现在删除了aa.txt了,相应的
-rw-r--r-- 1 linuxman linuxman 0 01-18 21:21 /home/linuxman/trashtest/aa.txt就写进去了。以后对这些文件的各种操作其实就是对.trashinfo.txt文件的读写而已。
    (二)现在我们看看回收站里边有什么内容 ,有三个选项-l,-p,-a,都不需要后加文件名的,下面说说它们有什么区别
$trsh -l    ---------->列出回收站的文件
aa.txt
$trsh -p    ---------->列出回收站的文件,包括绝对路径
/home/linuxman/trashtest/aa.txt  ---------->这个信息可以让你知道原来删除的文件放在哪个地方
$trsh -a    --------->也是列出回收站里边的文件,并且把文件的所有信息都显示了
-rw-r--r-- 1 linuxman linuxman 0 01-18 21:21 /home/linuxman/trashtest/aa.txt
     (三)现在试着把aa.txt文件给恢复过来吧,这里有两个选项-r和-R ,代表recover的意思。-r后面要接文件名,表示要恢复那些文件,-R不需要加上需要恢复的文件,因为它代表把回收站里边的所有文件都恢复过来,也免得你一个一个的恢复那么麻烦嘛。
$trsh -r aa.txt
$ls
aa.txt        -------------->好了,aa.txt文件又出来了
$trsh -l   
$              ------------->恩,意料之内,回收站里边没文件了,因为之前里边就一个aa.txt,
$ls
aa.txt         -------------->aa.txt又回来了
    如果觉得没必要列举一些你不想看到的信息的话,还有一个选项-t 格式为:
$trsh -d [dfl] d代表目录,f代表普通文件,l代表符号连接

      (四)那当我们确实觉得回收站里边的文件对我们来说是毫无价值的时候,我们就真的要删除他们来 ,好,给大家再介绍两个选项-d和-D,代表 delete,这是真的是delete的了。-d后边要输入文件名,表示要彻底删除哪个文件,-D则表示把回收站清空
$trsh -l
aa.txt
$trsh -d aa.txt
$trsh -l           ------------------>现在看到回收站里的文件真的没了
       (五)其他选项还有-h,-v也就是显示帮助信息和回收站的版本而已。
  
    好了,基本功能我们已经测试过了,一个回收站也算完成了。当然以后还要完善,大家有空没事可以拿来玩玩,不用担心文件真的被删除的,呵呵。也当作顺便帮我测试一下找些bug。另外大家觉得有什么功能需要添加的话也可以提出来,我尽量加上去。
     

下面是bash实现的代码:
#!/bin/bash
#

PREFIX=".trash_"
ARCERR=55
TRASHINFO="$HOME/.trashinfo.txt"
TMPFILE="$HOME/.$TMPFILE.txt"

if [ $# -eq 0 ]
then
  echo "trsh -h"
  echo "for more infomation"
  exit $ARCERR
fi

case "$1"
in
  -a)cat $TRASHINFO
     ;;

  -D)echo "Clear the trash?(y/n)"
     read answer
     if [ "$answer" = "n" ]
     then
        :
     else
       while read line
       do
         line=`echo $line | awk '{print $8}'`
         PARPATH=${line%/*}
         FILENAME=${line##*/}
         DELFILE=`echo $PREFIX$FILENAME`
         rm -rf $PARPATH/$DELFILE
       done < $TRASHINFO
       : > $TRASHINFO
     fi
     ;;

  -d)key=0
     for file in $*
     do
       if [ $key -eq 0 ]
       then
         let "key += 1"
       else
         LINE=`sed -e "/$file$/p" $TRASHINFO`
         LINE=`echo $LINE | awk '{print $8}'`
         PARPATH=${LINE%/*}
         FILENAME=${LINE##*/}
         DELFILE=`echo $PREFIX$FILENAME`
         echo "Delete file $FILENAME?(y/n)"
         read answer
         if [ $answer = "y" ]
         then
           rm -rf $PARPATH/$DELFILE
           sed -e "/$FILENAME$/d" $TRASHINFO > $TMPFILE
           mv $TMPFILE $TRASHINFO
         else
           :
         fi
       fi
     done
     ;;

  -h)echo "  -a files all information"
     echo "  -D clear the trash"
     echo "  -d clear file(s) in the trash"
     echo "  -h for help"
     echo "  -l list files in the trash "
     echo "  -m delete file(s)"
     echo "  -p list files with path"
     echo "  -R recover all files from trash"
     echo "  -r recover file(s) from trash"
     echo "  -v trash version"
     ;;

  -l)while read line
     do
       echo ${line##*/}
     done < $TRASHINFO
     ;;

  -m)key=0
     for file in $*
     do
       if [ $key -eq 0 ]
       then
         let "key += 1"
       else
         echo $file | grep "/"
         if [ $? -eq 0 ]
         then
           FILEDIR=${file%/*}
           FILENAME=${file##*/}
           cd $FILEDIR
           if [ $? -eq 0 ]
           then
             FILEPATH=`pwd`
             FILEINFO=`ls -ld $FILENAME`
             FILEINFO=`echo "$FILEINFO" |cut -d" " -f-7`
             ls $FILENAME
             if [ $? -eq 0 ]
             then
               echo "$FILEINFO"" ""$FILEPATH/$FILENAME" >> $TRASHINFO
               mv $FILENAME $PREFIX$FILENAME
             else
               :
             fi
           else
             :
           fi
         else
           FILENAME=$file
           FILEINFO=`ls -ld $file`
           ls $file &> /dev/null
           if [ $? -eq 0 ]
           then
             FILEINFO=`echo "$FILEINFO" |cut -d" " -f-7`
             FILEPATH=`pwd`
             echo "$FILEINFO"" ""$FILEPATH/$FILENAME" >> $TRASHINFO
             mv $FILENAME $PREFIX$FILENAME
            else
              :
            fi
         fi
       fi
     done
     ;;

  -p)while read line
     do
       LINE=`echo $line | cut -d" " -f8`
       echo $LINE
     done < $TRASHINFO
     ;;

  -R)while read line
     do
         line=`echo $line | cut -d" " -f8`
         FILENAME=${line##*/}
         PARPATH=${line%/*}
         RECOVERFILE=`echo $PREFIX$FILENAME`
         mv $PARPATH/$RECOVERFILE $PARPATH/$FILENAME
         sed -e "/$FILENAME$/d" $TRASHINFO > $TMPFILE
         mv $TMPFILE $TRASHINFO
     done < $TRASHINFO
     ;;

  -r)if [ $# -lt 2 ]
     then
       echo "No input file"
       exit $ARCERR
     fi
     key=0
     for file in $*
     do
       if [ $key -eq 0 ]
       then
         let "key += 1"
       else
         LINE=`grep "$file" $TRASHINFO`
         LINE=`echo $LINE | cut -d" " -f8`
         PARPATH=${LINE%/*}
         FILENAME=${LINE##*/}
         RECOVERFILE=$PREFIX$FILENAME
         mv $PARPATH/$RECOVERFILE $PARPATH/$FILENAME
         sed -e "/$FILENAME$/d" $TRASHINFO > $TMPFILE
         mv $TMPFILE $TRASHINFO
       fi
     done
     ;;

  -t)if [ $# -lt 2 ]
     then
       echo "not enough arguments"
     else
       case "$2"
       in
          d)sed -n "/^d/p" $TRASHINFO
          ;;
          f)sed -n "/^-/p" $TRASHINFO
          ;;
          l)sed -n "/^l/p" $TRASHINFO
          ;;
       esac
     fi
     ;;
  -v)echo "version 1.01"
     ;;

   *)echo "No options or options error"
     echo "trsh -h for help"
     ;;
esac  

对shell还不是很熟,大家多指点一下小弟。

[ 本帖最后由 zwylinux 于 2007-8-15 10:31 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-08-15 09:06 |只看该作者
支持一下,劳动成果

代码最好用[code]引起来

论坛徽章:
0
3 [报告]
发表于 2007-08-15 10:59 |只看该作者

确实确实

支持一下。

论坛徽章:
0
4 [报告]
发表于 2007-08-15 11:00 |只看该作者
支持!回头测试一下

论坛徽章:
0
5 [报告]
发表于 2007-08-15 11:02 |只看该作者
支持!!!

论坛徽章:
0
6 [报告]
发表于 2007-08-17 11:58 |只看该作者
-d)key=0
     for file in $*
     do
       if [ $key -eq 0 ]
       then
         let "key += 1"
       else
提一个问题,这个怎么解释?呵呵
谢谢
还有如果从$0开始,如果我有个文件名,就叫trsh,会出现什么问题?

论坛徽章:
0
7 [报告]
发表于 2007-08-17 12:08 |只看该作者
这段的意思是处理命令行参数时略过程序名。
$0本来就是指代trsh的。

论坛徽章:
0
8 [报告]
发表于 2007-08-17 13:10 |只看该作者
不错!支持并测试一下

论坛徽章:
0
9 [报告]
发表于 2007-08-17 13:46 |只看该作者
原帖由 zwylinux 于 2007-8-17 12:08 发表
这段的意思是处理命令行参数时略过程序名。
$0本来就是指代trsh的。

如果从$1开始,比如有文件名,为-a
会不会有问题,比如trsh -a -a
或者其他的参数?
还有,如果文件名有以.开头,或者是$等特殊字符,是不是会引起问题?
trsh -m ./.xxx
这样的形式?or trsh -m 'ab$a'?
那个掠过,应该是要从$2开始吧,$1还是参数呢

论坛徽章:
0
10 [报告]
发表于 2007-08-17 15:49 |只看该作者
原帖由 mxbao 于 2007-8-17 13:46 发表

如果从$1开始,比如有文件名,为-a
会不会有问题,比如trsh -a -a
或者其他的参数?
还有,如果文件名有以.开头,或者是$等特殊字符,是不是会引起问题?
trsh -m ./.xxx
这样的形式?or trsh -m 'ab$a'?
那个掠 ...

ls的兄弟可以测试一下呀,有问题我就改。
毕竟这个程序也不是很完善的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP