-
Notifications
You must be signed in to change notification settings - Fork 0
/
my_rm.sh
158 lines (142 loc) · 4.18 KB
/
my_rm.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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/bin/sh
# by vegetablebird last modified 2020.08.21
# USAGE: (1) ln -s $PWD/my_rm.sh ~/.local/bin/rm
# (2) export PATH=~/.local/bin:$PATH
# (3) which rm
#FEATURE: Try to create a new trash directory for each rm command
# but not guaranteed if two rm commands is committed at a same time
#FEATURE: If two files(directores) are removed with same name by a single rm command,
# they will be put into different trash directories
#FEATURE: There is a log_file in the corresponding trash directory,
# unless removing a file with the same name as log_file (without warning message throwing)
#Bug1: not support space. e.g.: rm -rf arch\ final\ project/
#Bug2: mv: cannot move ‘../results/My-mix33/m5out/’ to ‘/home/vegetablebird/.trash/2017-08-06/21:03:15.99453/m5out’: Directory not empty // IGNORE??
#TODO: /home/vegetablebird/.local/bin/rm: unimplemented arg: -fr, use /bin/rm
#TODO: log_file=original_command -> log_file=rm_cmd (cmd, remove_command)
#TODO: add undo command (restore removed data)
ori_rm=/bin/rm
trash_dir=/home/vegetablebird/.trash
preserve_days=90
log_file=original_command
function actually_rm
{
if [ "`ps -A | grep rm | wc -l`" -gt "2" ] || [ -f $trash_dir/rming ]
then
# echo $0: rm is running, skipping actually_rm
# ps -A | grep rm
exit
fi
touch $trash_dir/rming
cur_year=`date +%Y`
cur_month=`date +%m`
cur_day=`date +%d`
cd $trash_dir
for f in `ls -d * | grep '[0-9]\+-[0-9]\+-[0-9]\+'`
do
file_year=`echo $f | sed 's/\([0-9]\+\)-[0-9]\+-[0-9]\+/\1/g'`
file_month=`echo $f | sed 's/[0-9]\+-\([0-9]\+\)-[0-9]\+/\1/g'`
file_day=`echo $f | sed 's/[0-9]\+-[0-9]\+-\([0-9]\+\)/\1/g'`
diff_year=$(( 10#$cur_year - 10#$file_year ))
diff_month=$(( 12*$diff_year + 10#$cur_month - 10#$file_month ))
diff_day=$(( 30*$diff_month + 10#$cur_day - 10#$file_day ))
if [ "$diff_day" -gt "$preserve_days" ]
then
$ori_rm -rf $f
fi
done
$ori_rm $trash_dir/rming
}
force=false
recursive=false
files=""
directories=""
not_exists=""
for arg in $@
do
if [[ $arg == -* ]]
then
if [ "$arg" == "-h" ] || [ "$arg" == "-help" ] || [ "$arg" == "--help" ]
then
echo -e "Usage: $0 [OPTION]... FILE..."
echo -e "Move the FILE(s) to trash_dir($trash_dir)."
echo -e "Check and Delete the files in trash_dir longer than $preserve_days days."
echo
echo -e " -f, --force\t\tignore nonexistent files and arguments"
echo -e " -r, -R, --recursive\tremove directories and their contents recursively"
echo -e " -h, -help, --help\tdisplay this help and exit"
echo -e "\t\t\tuse '$ori_rm --help' for the conventional rm help"
echo
echo -e "Created by vegetablebird"
exit 0
elif [ "$arg" == "-f" ] || [ "$arg" == "--force" ]
then
force=true
elif [ "$arg" == "-r" ] || [ "$arg" == "-R" ] || [ "$arg" == "--recursive" ]
then
recursive=true
elif [ "$arg" == "-rf" ]
then
force=true
recursive=true
else
echo "$0: unimplemented arg: $arg, use $ori_rm"
$ori_rm $@
exit $?
fi
elif [ -f "$arg" ] || [ -L "$arg" ]
then
files="$files $arg"
elif [ -d "$arg" ]
then
directories="$directories $arg"
else
not_exists="$not_exists $arg"
fi
done
# Check the operands
if [ "$files" == "" ] && [ "$directories" == "" ] && [ "$not_exists" == "" ]
then
echo "$0: missing operand"
exit 1
fi
if [ "$force" = false ] && [ "$not_exists" != "" ]
then
for f in $not_exists
do
echo "$0: cannot remove '$f': No such file or directory"
done
exit 1
fi
if [ "$recursive" = false ] && [ "$directories" != "" ]
then
for f in $directories
do
echo "$0: cannot remove '$f': Is a directory"
done
exit 1
fi
# Move files to a directory in .trash
rm_dir=""
for f in $files $directories
do
filename=`echo $f | sed -e 's/^.*\/\([^\/]\+\)\/\?$/\1/g'`
if [ "$rm_dir" == "" ] || [ -f $rm_dir/$filename ] || [ -d $rm_dir/$filename ]
then
rm_dir=$trash_dir/`date +%F/%T.%5N`
if [ -f $rm_dir/$f ] || [ -d $rm_dir/$f ]
then
echo "$0: cannot find a valid trash directory"
exit 1
fi
mkdir -p $rm_dir
echo "$LOGNAME@$HOSTNAME:`pwd`$ $0 $@" >> $rm_dir/$log_file
fi
mv $f $rm_dir
if [ "$?" == "1" ]
then
echo "GET Bug2: mv: cannot move ‘...’ to ‘...’: Directory not empty"
fi
done
# Actually rm the old files
actually_rm &
exit 0