-
Notifications
You must be signed in to change notification settings - Fork 23
/
trash_rm
244 lines (221 loc) · 6.62 KB
/
trash_rm
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#!/bin/bash
# Author: CHEN Feng <chen3feng@gmail.com>
# Date: 2012-01-18
# Description: a rm function with trash support
# ===========================================================================
# How to use:
# ---------------------------------------------------------------------------
# 1. Download this script
# 2. Add the following line into your ~/.bashrc
# ------------------------------
# source /path/to/trash_rm
# ------------------------------
# 3. Relogin
# 4. Your rm command is replaced now (you can also call original rm by /bin/rm)
# 5. Enjoy it!
#
# ===========================================================================
# How to view the removed files?
# ---------------------------------------------------------------------------
# Using the following commands:
# ----------------------------------------------
# cd ~/.trash
# ls lastday/
# ----------------------------------------------
# All removed file are organized by removed date and time.
#
# ===========================================================================
# How to restore removed files?
# ---------------------------------------------------------------------------
# You can use mv or cp command to restore
#
# ===========================================================================
# How to remove file permanently?
# ---------------------------------------------------------------------------
# Add -D flag to rm command, (-D means directly)
# To removed the files in trash, just using the rm command
# ----------------------------------------------
# rm ~/.trash/path/to/removed/files.
# ----------------------------------------------
# The path of trash directory
TRASH_DIR=$HOME/.local/trash
if [[ "$OSTYPE" == "darwin"* ]]; then
realpath() {
[[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}
fi
# bool _file_in_dir(string file, string dir)
function _file_in_dir() {
local file
local dir
file="$(realpath "$1")"
dir="$2"
file_dir="$file"
while :; do
if [ "$file_dir" = "$dir" ]; then
return 0;
fi
file_dir=`dirname "$file_dir"`
if [ "$file_dir" = "/" ]; then
return 1
fi
done
return 1
}
function _move_to_trash() {
local verbose=$1
local arg=$2
local osas
# Move it to the ~/.Trash dir under macos
if [ `uname` = Darwin ]; then
osas="tell application \"Finder\" to delete POSIX file \"${PWD}/${arg}\""
if [ -n "$verbose" ]; then
osascript -e "$osas"
else
osascript -e "$osas" >/dev/null
fi
return
fi
if [ ! -d "$TRASH_DIR" ]; then
mkdir -p $TRASH_DIR
echo "Trash dir $TRASH_DIR created."
fi
local timestamp date_dir target_name
# Mac's date doesn't support %N, and linux eval $RANDOM at load time
if [ `uname` = Darwin ]; then
timestamp=`date +%Y%m%d.%H%M%S.``printf "%05d" $RANDOM`
else
timestamp=`date +%Y%m%d.%H%M%S.%N`
fi
# Put file into corresponding dir according removing date
date_dir="$TRASH_DIR/${timestamp:0:8}"
if [ ! -e "$date_dir" ]; then
mkdir -p "$date_dir"
fi
# Make user easy locating dir of today
/bin/rm -f "$TRASH_DIR/lastday"
ln -sf "$date_dir" "$TRASH_DIR/lastday"
target_name="$date_dir/${timestamp} `basename "$arg"`"
if [ -n "$verbose" ]; then
echo "move $arg to $target_name"
fi
mv "$arg" "$target_name"
}
# This function will replace the rm command of system.
function rm() {
local direct
local force
local interactive
local recursive
local verbose
local trash_dir="$TRASH_DIR"
if [[ `getopt 2>/dev/null` == ' --' ]]; then
# Mac's getopt doesn't support long options
if ! rm_args=`getopt firDRv "$@"`; then
return 1;
fi
else
if ! rm_args=`getopt -o firDRv -n rm --long direct,force,help,interactive,recursive,verbose,version -- "$@"`; then
return 1;
fi
fi
eval set -- "$rm_args"
while [ -n "$1" ]; do
case "$1" in
-D|--direct)
direct='-D'
shift;;
-f|--force)
force="-f"
shift;;
-i|--interactive)
interactive="-i"
shift;;
-r|-R|--recursive)
recursive="-r"
shift;;
-v|--verbose)
verbose="-v"
shift;;
--help)
/bin/rm "$1"
echo -e "\nAddition options:\n -D, --direct remove directly, don't use trash"
return;;
--version)
/bin/rm "$1"
return;;
--)
shift;
break ;;
*)
echo "unknown option $1" >&2
return 1;;
esac
done
local arg
local confirm
local error
local timestamp
local date_dir
local target_name
if [ -n "$direct" ]; then
/bin/rm $force $recursive $verbose $interactive "$@"
return $?
fi
if [[ $# == 0 ]]; then
if [[ -z "$force" ]]; then
/bin/rm
fi
return
fi
error=0
for arg in "$@"; do
if _file_in_dir "$arg" "$trash_dir"; then
/bin/rm $force $recursive $verbose $interactive "$arg"
continue
fi
if ! stat "$arg" &> /dev/null; then
if [ -z "$force" ]; then
echo "rm: cannot remove \`$arg': No such file or directory"
error=1
fi
continue
fi
if [[ -d "$arg" && ! -L "$arg" && -z "$recursive" ]]; then
echo "cannot remove \`$arg': Is a directory"
error=1
continue
fi
if [ -n "$interactive" ]; then
local file_type
if [ -d "$arg" ]; then
file_type="directory"
elif [ -L "$arg" ]; then
file_type="symbolic link"
else
file_type="file"
fi
echo -n "rm: remove $file_type \`$arg'?"
read confirm
if [ "$confirm" != "y" ]; then
continue;
fi
fi
if [ -L "$arg" ]; then
# Put symbolic link into trash is meaningless, remove it directly.
if [ -n "$verbose" ]; then
echo "rm symbolic link $arg"
fi
/bin/rm "$arg"
else
_move_to_trash "$verbose" "$arg"
fi
done
return $error
}
trash_clean() {
local item
for item in $TRASH_DIR/* ; do
/bin/rm -fr "$item"
done
}