-
Notifications
You must be signed in to change notification settings - Fork 4
/
backup
217 lines (200 loc) · 9.77 KB
/
backup
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
#!/bin/bash
## ------------------------------------
## Made By: Michael Yochpaz (C) 2020
## https://github.com/MichaelYochpaz/Backup-Script
## Version: 1.2.0
## License: GPLv3
## ------------------------------------
## -------------- Usage ---------------
## The script generates a tar.gz backup file of a folder, and according to user's given arguments,
## can upload it to a cloud service using rclone and remove the local copy.
##
## ------------ Requirments -----------
## - In order to use the upload feature, rclone must be installed and have at least one cloud service setup in config.
## ------------------------------------
##
## Usage: backup [-n <name>] [-s <path>] [-e <pattern>]... [-u <path>] [-p <API key>] [-r] [-y] [-v] <path-to-backup>
##
## Options:
## -n <name> Sets the tar.gz file name [default: "backup"]
## -s <path> Path to which the generated backup file will be saved to [default: current working directory]
## -e <pattern> Exclude a pattern (specific files / folders) from being backed up
## -u <path> rclone path to which the backup file will be uploaded to (not providing one will skip the upload process)
## -p <API key> Sends a Pushbullet notification once backup is done
## -r Removes local copy of backup file after it's been uploaded
## -y Skip warnings (Warnings require user input to continue by default)
## -v Uses '-v' option when running tar and rclone
##
## Commands:
## -h Displays this help message and exists.
##
## Examples:
## backup "/home/user/important_stuff"
## backup -u "GDrive:/Backups" -r -y -p "XXXXXXXXXXXXXXXX" "/home/user/important_stuff/"
## backup -n "important-stuff-backup" -s "/home/user/backups" -e "*.pdf" -e "important_stuff/dont_backup_this_folder" "/home/user/important_stuff/"
##
## --------- Configuration ------------
BACKUP_NAME="backup" # Backup file name. date will be added to file name after this string.
BACKUP_FOLDER="" # Folder to backup (full path).
EXCLUDES=() # Exclusion patterns array. Usage example: ("*.mkv" "*.pdf" "important_stuff/dont_backup_this_folder")
SAVE_FOLDER="$PWD" # Folder to save backup file to (full path)
RCLONE_FOLDER="" # rclone folder path to upload backup file to. Leave empty to skip the upload process.
PUSHBULLET_API_KEY="" # Pusbullet API key for notifications.
REMOVE_LOCAL=false # Boolean - Remove local backup file after upload.
SKIP_WARNINGS=false # Boolean - Skip warnings.
VERBOSE=false # Boolean - Use verbose mode when running tar and rclone.
PUSHBULLET_TITLE="Backup Script" # Pusbullet - Notification title.
PUSHBULLET_MESSAGE_START="Backup script " # Pushbullet - Notification messages will start with this string, followed by one of the followings:
PUSHBULLET_MESSAGE_FINISHED_SUCCESS="finished successfully." # Pusbullet - Message will be shown if the script ran successfully.
PUSHBULLET_MESSAGE_FINISHED_ERRORS="finished with errors." # Pusbullet - Message will be shown if the script finished with errors.
PUSHBULLET_MESSAGE_FAIL="failed." # Pusbullet - Message will be shown if the script has failed.
## ------------------------------------
usage() { echo "Usage: $(basename $0) [-n <name>] [-s <path>] [-e <pattern>]... [-u <path>] [-p <API key>] [-r] [-y] [-v] <path-to-backup>
Use $(basename $0) -h for additional info."; exit 1; }
# if there is a Pushbullet API key, send a Pushbullet notification. uses a parameter for message's body
pushbullet() { if [ -n "$PUSHBULLET_API_KEY" ]; then curl -u "$PUSHBULLET_API_KEY": https://api.pushbullet.com/v2/pushes -d type=note -d \
title="$PUSHBULLET_TITLE" -d body="$PUSHBULLET_MESSAGE_START$1 " >/dev/null 2>&1; fi }
ERROR=false # sets to true if there's an error. used for final exit code of the script.
C0='\033[0m' # ANSI - no color
C1='\033[0;32m' # ANSI - success - green
C2='\033[1;31m' # ANSI - error - red
C3='\033[0;36m' # ANSI - information - cyan
C4='\033[0;33m' # ANSI - variables/paths - orange
while getopts ":n:e:s:u:p:ryvh" arg; do
case $arg in
n)
BACKUP_NAME=${OPTARG}
;;
e)
EXCLUDES+=("${OPTARG}")
;;
s)
SAVE_FOLDER=${OPTARG}
;;
u)
RCLONE_FOLDER=${OPTARG}
;;
p)
PUSHBULLET_API_KEY=${OPTARG}
;;
r)
REMOVE_LOCAL=true
;;
y)
SKIP_WARNINGS=true
;;
v)
VERBOSE=true
;;
h)
echo " Usage: $(basename $0) [-n <name>] [-s <path>] [-e <pattern>]... [-u <path>] [-p <API key>] [-r] [-y] [-v] <path-to-backup>
Options:
-n <name> Sets the tar.gz file name [default: "backup"]
-s <path> Path to which the generated backup file will be saved to [default: current working directory]
-e <pattern> Exclude a pattern (specific files / folders) from being backed up
-u <path> rclone path to which the backup file will be uploaded to (not providing one will skip the upload process)
-p <API key> Sends a Pushbullet notification once backup is done
-r Removes local copy of backup file after it's been uploaded
-y Skip warnings (Warnings require user input to continue by default)
-v Uses '-v' option when running tar and rclone
Commands:
-h Displays this help message and exists.
Examples:
$(basename $0) \"/home/user/important_stuff\"
$(basename $0) -u \"GDrive:/Backups\" -r -y -p \"XXXXXXXXXXXXXXXX\" \"/home/user/important_stuff/\"
$(basename $0) -n \"important-stuff-backup\" -s \"/home/user/backups\" -e \"*.pdf\" -e \"important_stuff/dont_backup_this_folder\" \"/home/user/important_stuff/\""
exit 0
;;
*)
usage
;;
esac
done
# positional argument - the folder that's going to be backed-up
if [[ -n "${@:$OPTIND:1}" ]]; then BACKUP_FOLDER=${@:$OPTIND:1}; fi
# if no backup folder was chosen, show usage
if [ -z "$BACKUP_FOLDER" ]; then usage; fi
# if BACKUP_FOLDER path doesn't exist, show error and exit
if [ ! -d $BACKUP_FOLDER ]; then
echo -e "${C2}Folder ${C4}$BACKUP_FOLDER ${C2}not found${C0}"
pushbullet "$PUSHBULLET_MESSAGE_FAIL"
exit 1
fi
# if SAVE_FOLDER path doesn't exist, show error and exit
if [ ! -d $SAVE_FOLDER ]; then
echo -e "${C2}Folder ${C4}$SAVE_FOLDER ${C2}not found${C0}"
pushbullet "$PUSHBULLET_MESSAGE_FAIL"
exit 1
fi
# if BACKUP_FOLDER path ends with a '/', remove it
if [ "${BACKUP_FOLDER: -1}" = "/" ]; then BACKUP_FOLDER=${BACKUP_FOLDER%?}; fi
# if SAVE_FOLDER path ends with a '/', remove it
if [ "${SAVE_FOLDER: -1}" = "/" ]; then SAVE_FOLDER=${SAVE_FOLDER%?}; fi
# if REMOVE_LOCAL is set to true, but rclone upload is not used, show a warning.
if [ "$REMOVE_LOCAL" = true ] && [ -z "$RCLONE_FOLDER" ] && [] "$SKIP_WARNINGS" = false ]; then
read -p "WARNING: '-r' argument to remove local backup file was used,
but no rclone path to upload backup flie to beforehand is set.
This will result in generating a backup file and deleting it after without it being uploaded anywhere.
Would you like to continue (Y/n) ?" -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 0; fi
fi
# ----- tar -----
echo -e "$(date +"%Y/%m/%d %T") ${C3}Generating tar.gz file"${C0}
FILENAME="${BACKUP_NAME}-$(date +%FT%H%M).tar.gz"
# generate a temporary file to store EXCLUDES in
EXCLUEDS_FILE=$(mktemp /tmp/backup.XXXXXX.txt)
if [ ! ${#EXCLUDES[@]} -eq 0 ]; then printf "%s\n" "${EXCLUDES[@]}" > "$EXCLUEDS_FILE"; fi
# run tar with or without '-v', according to VERBOSE value
if [ "$VERBOSE" = true ]; then tar -cvzf "$SAVE_FOLDER/$FILENAME" -C "$BACKUP_FOLDER/.." -X $EXCLUEDS_FILE "$(basename "$BACKUP_FOLDER")"; \
else tar -czf "$SAVE_FOLDER/$FILENAME" -C "$BACKUP_FOLDER/.." -X $EXCLUEDS_FILE "$(basename "$BACKUP_FOLDER")"; fi
# remove temporary file
rm $EXCLUEDS_FILE
# tar commmand finished successfully (exit code = 0)
if [ "$?" = 0 ]; then
echo -e "$(date +"%Y/%m/%d %T") ${C1}Backup file generated and saved successfully to ${C4}$SAVE_FOLDER/$FILENAME ($(du -h "$SAVE_FOLDER/$FILENAME" | cut -f1))${C0}"
# tar commmand didn't run successfully (exit code != 0)
else
echo -e "$(date +"%Y/%m/%d %T") ${C2}Backup file generation failed${C0}"
# if a file was generated during the (failed) tar process, remove it
if [ -f "$SAVE_FOLDER/$FILENAME" ]; then rm "$SAVE_FOLDER/$FILENAME"; fi
pushbullet "$PUSHBULLET_MESSAGE_FAIL"
exit 1
fi
# ----- rclone -----
if [ -n "$RCLONE_FOLDER" ]; then
echo -e "$(date +"%Y/%m/%d %T") ${C3}Uploading backup file to ${C4}$RCLONE_FOLDER${C0}"
# run rclone with or without '-v', according to VERBOSE value
if [ "$VERBOSE" = true ]; then rclone copy "$SAVE_FOLDER/$FILENAME" -v "$RCLONE_FOLDER"; else rclone copy "$SAVE_FOLDER/$FILENAME" "$RCLONE_FOLDER"; fi
# rclone commmand finished successfully (exit code = 0)
if [ "$?" = 0 ]; then
echo -e "$(date +"%Y/%m/%d %T") ${C1}Backup file uploaded successfully${C0}"
# rclone command didn't run successfully (exit code != 0)
else
ERROR=true
echo -e "$(date +"%Y/%m/%d %T") ${C2}Upload failed${C0}"
if [ "$REMOVE_LOCAL" = true ] && [ "$SKIP_WARNINGS" = false ]; then
read -p "WARNING: Would you like to continute and remove local copy of the backup file even though upload wasn't successful (Y/n) ? " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "$(date +"%Y/%m/%d %T") ${C2}Script finished with errors${C0}"
exit 1
fi
fi
fi
fi
# remove local backup if REMOVE_LOCAL setting used
if [ "$REMOVE_LOCAL" = true ]; then
rm "$SAVE_FOLDER/$FILENAME"
echo -e "$(date +"%Y/%m/%d %T") ${C1}Local file removed${C0}"
fi
# print, send Pushbullet notification (if used), and exit using correct code according to ERROR's value
if [ "$ERROR" = false ]; then
echo -e "$(date +"%Y/%m/%d %T") ${C1}Script finished successfully${C0}"
pushbullet "$PUSHBULLET_MESSAGE_FINISHED_SUCCESS"
exit 0;
else
echo -e "$(date +"%Y/%m/%d %T") ${C2}Script finished with errors${C0}"
pushbullet "$PUSHBULLET_MESSAGE_FINISHED_ERRORS"
exit 1
fi