一个计算机技术爱好者与学习者

0%

好好学Shell:安全删除

1. 前言

很多时候,我们会误删文件,那么一个回收站就很有必要了。看了一些回收站的实现,都比较复杂,干脆自己写一个。

思路:使用mv替换rm,把想要删除的文件暂时移动到回收站。

2. 安全删除脚本

1、编写安全删除脚本,saferm.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/bin/bash

TRASHDIR="${HOME}/.saferm/trash"
[[ ! -d ${TRASHDIR} ]] && mkdir -p ${TRASHDIR}

function usage(){
echo -e "
Brief: move directory and files to ~/.local/trash
Usage: alias rm=/path/to/saferm.sh
rm <dir>
rm <file>
rm <file1> <file2>
"
}

function main(){
local now=$(date "+%Y%m%d%H%M%S")
local destdir="${TRASHDIR}/${now}"
mkdir ${destdir}

local opt
while getopts "h" opt
do
case $opt in
h)
usage && exit 0 ;;
\?)
usage && exit 0 ;;
esac
done

local files="$*"
local successfiles=""
for file in ${files};do
mv ${file} ${destdir} && successfiles=${successfiles}" "${file}
done
if [[ -z "${successfiles}" ]];then
echo -e "\033[31mNothing to do! Check the source filenames please!\033[0m"
else
echo -e "${successfiles} have been moved to \033[31m${destdir}\033[0m"
fi
}

main "$@"

2、使用方法
编辑 .bash_profile ,添加内容

1
2
# saferm
alias rm="/path/to/saferm.sh"

添加内容完成, source .bash_profile ,rm命令就被替换为saferm脚本了。

以上,安全删除的功能就完成了,自己偶尔手动清理下 TRASHDIR 中的文件。
以下内容可选,是对该saferm脚本的补充。

3. 清理回收站脚本

1、清理回收站脚本,cleartrash.sh

1
2
3
4
5
6
7
8
#!/bin/bash
# Clear files in trash that been removed 3 days ago.

TRASHDIR="${HOME}/.saferm/trash"
CLEARLOG="${TRASHDIR}/clear.log"
[[ -d ${TRASHDIR} ]] \
&& find ${TRASHDIR} -mindepth 1 -type d -mtime +2 \
| xargs rm -rfv | tee -a ${CLEARLOG}

2、使用方法
编辑 .bash_profile ,添加内容

1
2
3
# saferm
alias rm="/path/to/saferm.sh"
alias cleartrash="/path/to/cleartrash.sh"

添加内容完成, source .bash_profile ,然后就可以使用 cleartrash 命令清理回收站了。

3、定时任务
参考《Linux设置定时任务》,添加定时任务。

crontab -e,添加定时任务,每天晚上执行一次:

1
5 0 * * * /bin/bash /path/to/cleartrash.sh

4. 进阶

saferm.sh 脚本存在一个严重bug:无法删除文件名带空格的文件,甚至会误删文件。
因为Shell默认以空格、Tab、回车作为值与值之间的分隔符,而不是做为文件名的一部分。如果文件名中带空格,就会被认为是多个文件。

修改 saferm.sh 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/bin/bash

TRASHDIR="${HOME}/.saferm/trash"
[[ ! -d ${TRASHDIR} ]] && mkdir -p ${TRASHDIR}

function usage(){
echo -e "
Brief: Move directories or files to ~/.local/trash
You can move 1-3 files with wildcard. More is unsupported.
If file name contains space, use quotation mark please.
Usage: alias rm=/path/to/saferm.sh
rm <dir>
rm <file>
rm *.<filetype>
rm <file1> <file2> <file3>
"
}

function main(){
local now=$(date "+%Y%m%d%H%M%S")
local destdir="${TRASHDIR}/${now}"
mkdir ${destdir}

local opt
while getopts "h" opt
do
case $opt in
h)
usage && exit 0 ;;
\?)
usage && exit 0 ;;
esac
done

local file1="$1"
local file2="$2"
local file3="$3"
local file4="$4"
local successfiles=""
[[ -n "${file1}" ]] && mv "${file1}" ${destdir} && successfiles=${successfiles}" "${file1}
[[ -n "${file2}" ]] && mv "${file2}" ${destdir} && successfiles=${successfiles}" "${file2}
[[ -n "${file3}" ]] && mv "${file3}" ${destdir} && successfiles=${successfiles}" "${file3}
[[ -n "${file4}" ]] && echo -e "\033[31mYou can move 1-3 files with wildcard. More is unsupported.\033[0m"
if [[ -z "${successfiles}" ]];then
echo -e "\033[31mNothing to do! Check the source filenames please!\033[0m"
else
echo -e "${successfiles} have been moved to \033[31m${destdir}\033[0m"
fi
}

main "$@"

5. 别人家的saferm

1、下载安装saferm.sh

1
2
3
git clone https://github.com/lagerspetz/linux-stuff
sudo mv linux-stuff/scripts/saferm.sh /bin
rm -Rf linux-stuff

2、编辑.bashrc文件,末尾添加

1
2
alias rm=saferm.sh
alias sudo='sudo '

3、使环境生效

1
source .bashrc

之后,再使用rm或者sudo rm命令,实际上执行的是mv操作,移动文件到Trash目录。

参考文档:Make “rm” Command To Move The Files To “Trash Can”

  • 本文作者: 好好学习的郝
  • 原文链接: https://www.voidking.com/dev-shell-saferm/
  • 版权声明: 本文采用 BY-NC-SA 许可协议,转载请注明出处!源站会即时更新知识点并修正错误,欢迎访问~
  • 微信公众号同步更新,欢迎关注~