-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathremove.sh
246 lines (222 loc) · 6.45 KB
/
remove.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
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
245
#!/bin/bash
##
## saferm.sh
## Safely remove files, moving them to GNOME/KDE trash instead of deleting.
## Made by Eemil Lagerspetz
## Login <vermind@drache>
##
## Started on Mon Aug 11 22:00:58 2008 Eemil Lagerspetz
## Last update Sat Aug 16 23:49:18 2008 Eemil Lagerspetz
##
version="1.16";
## flags (change these to change default behaviour)
recursive="" # do not recurse into directories by default
verbose="true" # set verbose by default for inexperienced users.
force="" #disallow deleting special files by default
unsafe="" # do not behave like regular rm by default
## possible flags (recursive, verbose, force, unsafe)
# don't touch this unless you want to create/destroy flags
flaglist="r v f u q"
# Colours
blue='\e[1;34m'
red='\e[1;31m'
norm='\e[0m'
DATE=`date +%Y%m%d%H`
DIR="/data/backup"
mkdir -p $DIR/trash/$DATE
ID=`id|awk '{print $1}'|awk -F "=" '{print $2}'|awk -F "(" '{print $1}'`
if [ $ID = 0 ];then
chmod -R 777 $DIR/trash
fi
## trashbin definitions
# this is the same for newer KDE and GNOME:
trash_desktops="$DIR/trash/$DATE"
# if neither is running:
trash_fallback="$DIR/trash/$DATE"
# use .local/share/Trash?
use_desktop=$( ps -U $USER | grep -E "gnome-settings|startkde|mate-session|mate-settings|mate-panel|gnome-shell|lxsession|unity" )
# mounted filesystems, for avoiding cross-device move on safe delete
filesystems=$( mount | awk '{print $3; }' )
if [ -n "$use_desktop" ]; then
trash="${trash_desktops}"
infodir="${trash}/../info";
for k in "${trash}" "${infodir}"; do
if [ ! -d "${k}" ]; then mkdir -p "${k}"; fi
done
else
trash="${trash_fallback}"
fi
usagemessage() {
echo -e "This is ${blue}saferm.sh$norm $version. LXDE and Gnome3 detection.
Will ask to unsafe-delete instead of cross-fs move. Allows unsafe (regular rm) delete (ignores trashinfo).
Creates trash and trashinfo directories if they do not exist. Handles symbolic link deletion.
Does not complain about different user any more.\n";
echo -e "Usage: ${blue}/path/to/saferm.sh$norm [${blue}OPTIONS$norm] [$blue--$norm] ${blue}files and dirs to safely remove$norm"
echo -e "${blue}OPTIONS$norm:"
echo -e "$blue-r$norm allows recursively removing directories."
echo -e "$blue-f$norm Allow deleting special files (devices, ...)."
echo -e "$blue-u$norm Unsafe mode, bypass trash and delete files permanently."
echo -e "$blue-v$norm Verbose, prints more messages. Default in this version."
echo -e "$blue-q$norm Quiet mode. Opposite of verbose."
echo "";
}
detect() {
if [ ! -e "$1" ]; then fs=""; return; fi
path=$(readlink -f "$1")
for det in $filesystems; do
match=$( echo "$path" | grep -oE "^$det" )
if [ -n "$match" ]; then
if [ ${#det} -gt ${#fs} ]; then
fs="$det"
fi
fi
done
}
trashinfo() {
#gnome: generate trashinfo:
bname=$( basename -- "$1" )
fname="${trash}/../info/${bname}.trashinfo"
cat <<EOF > "${fname}"
[Trash Info]
Path=$PWD/${1}
DeletionDate=$( date +%Y-%m-%dT%H:%M:%S )
EOF
}
setflags() {
for k in $flaglist; do
reduced=$( echo "$1" | sed "s/$k//" )
if [ "$reduced" != "$1" ]; then
flags_set="$flags_set $k"
fi
done
for k in $flags_set; do
if [ "$k" == "v" ]; then
verbose="true"
elif [ "$k" == "r" ]; then
recursive="true"
elif [ "$k" == "f" ]; then
force="true"
elif [ "$k" == "u" ]; then
unsafe="true"
elif [ "$k" == "q" ]; then
unset verbose
fi
done
}
performdelete() {
# "delete" = move to trash
if [ -n "$unsafe" ]
then
if [ -n "$verbose" ];then echo -e "Deleting $red$1$norm"; fi
#UNSAFE: permanently remove files.
rm -rf -- "$1"
else
if [ -n "$verbose" ];then echo -e "Moving $blue$k$norm to $red${trash}$norm"; fi
mv -b -- "$1" "${trash}" # moves and backs up old files
fi
}
askfs() {
detect "$1"
if [ "${fs}" != "${tfs}" ]; then
unset answer;
until [ "$answer" == "y" -o "$answer" == "n" ]; do
echo -e "$blue$1$norm is on $blue${fs}$norm. Unsafe delete (y/n)?"
read -n 1 answer;
done
if [ "$answer" == "y" ]; then
unsafe="yes"
fi
fi
}
complain() {
msg=""
if [ ! -e "$1" -a ! -L "$1" ]; then # does not exist
msg="File does not exist:"
elif [ ! -w "$1" -a ! -L "$1" ]; then # not writable
msg="File is not writable:"
elif [ ! -f "$1" -a ! -d "$1" -a -z "$force" ]; then # Special or sth else.
msg="Is not a regular file or directory (and -f not specified):"
elif [ -f "$1" ]; then # is a file
act="true" # operate on files by default
elif [ -d "$1" -a -n "$recursive" ]; then # is a directory and recursive is enabled
act="true"
elif [ -d "$1" -a -z "${recursive}" ]; then
msg="Is a directory (and -r not specified):"
else
# not file or dir. This branch should not be reached.
msg="No such file or directory:"
fi
}
asknobackup() {
unset answer
until [ "$answer" == "y" -o "$answer" == "n" ]; do
echo -e "$blue$k$norm could not be moved to trash. Unsafe delete (y/n)?"
read -n 1 answer
done
if [ "$answer" == "y" ]
then
unsafe="yes"
performdelete "${k}"
ret=$?
# Reset temporary unsafe flag
unset unsafe
unset answer
else
unset answer
fi
}
deletefiles() {
for k in "$@"; do
fdesc="$blue$k$norm";
complain "${k}"
if [ -n "$msg" ]
then
echo -e "$msg $fdesc."
else
#actual action:
if [ -z "$unsafe" ]; then
askfs "${k}"
fi
performdelete "${k}"
ret=$?
# Reset temporary unsafe flag
if [ "$answer" == "y" ]; then unset unsafe; unset answer; fi
#echo "MV exit status: $ret"
if [ ! "$ret" -eq 0 ]
then
asknobackup "${k}"
fi
if [ -n "$use_desktop" ]; then
# generate trashinfo for desktop environments
trashinfo "${k}"
fi
fi
done
}
# Make trash if it doesn't exist
if [ ! -d "${trash}" ]; then
mkdir "${trash}";
fi
# find out which flags were given
afteropts=""; # boolean for end-of-options reached
for k in "$@"; do
# if starts with dash and before end of options marker (--)
if [ "${k:0:1}" == "-" -a -z "$afteropts" ]; then
if [ "${k:1:2}" == "-" ]; then # if end of options marker
afteropts="true"
else # option(s)
setflags "$k" # set flags
fi
else # not starting with dash, or after end-of-opts
files[++i]="$k"
fi
done
if [ -z "${files[1]}" ]; then # no parameters?
usagemessage # tell them how to use this
exit 0;
fi
# Which fs is trash on?
detect "${trash}"
tfs="$fs"
# do the work
deletefiles "${files[@]}"