-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathmultibackup
executable file
·178 lines (154 loc) · 5.01 KB
/
multibackup
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
#!/usr/bin/env bash
[[ -n "${DEBUG}" ]] && set -x
###
# Configuration
###
# Use "~/.multibackup" as default config, if $CONFIG is not specified
CONFIG="${CONFIG:-${HOME}/.multibackup.conf}"
###
# Functions
###
# Color helpers
color_red=$(tput setaf 1)
color_yellow=$(tput setaf 3)
color_green=$(tput setaf 2)
color_reset=$(tput sgr0)
# Logging prefix helper
prefix(){
# Check if placeholders variables are given
if [[ -n "${current_action}" && -n "${current_task}" && -n "${total_tasks}" ]]; then
# Return prefix
echo "[${current_action}] [${current_task}/${total_tasks}] "
fi
}
# Logging helpers
debug() {
echo "$(prefix)[DEBUG] $@ " 1>&2
}
success() {
echo "$(prefix)${color_green}[SUCCESS]${color_reset} $@" 1>&2
}
info() {
echo "$(prefix)${color_yellow}[INFO]${color_reset} $@" 1>&2
}
error() {
echo "$(prefix)${color_red}[ERROR]${color_reset} $@" 1>&2
}
# Strip all redundant slashes in file paths
strip_duplicate_slashes_in_path(){
# Backup current shopt options
shoptBackup=$(shopt -p)
# Set extented globbing
shopt -s extglob
# Substitute input (turn multiple slashes into single one) and return
echo "${@//+(\/)//}"
# Restore shopt
eval "$oldShoptOptions" &> /dev/null
}
# Replace all slashes with dashes
replace_slash_with_dash(){
input="${@////-}" # replace all slashes with dashes
input="${input/#-/}" # remove possible starting dash
output="${input/%-/}" # as well as possible trailing dash
echo "${output}"
}
###
# Logic
###
# Check for config file then read and source
if [[ -f "${CONFIG}" ]]; then
. "${CONFIG}"
else
error "Couldn't find configuration file \"${CONFIG}\""
exit 1
fi
# Iterate through tar_excludes to create a "--exclude=XXX" combination string
tar_exclude_parameters=()
if [[ "${#tar_excludes[@]}" -ne 0 ]]; then
# Run each pre command
for parameter in "${tar_excludes[@]}"; do
tar_exclude_parameters+=( "--exclude=${parameter}" )
done
fi
# Set prefix variables for pre-commands
current_action="pre-command"
current_task=1
total_tasks="${#pre_commands[@]}"
# Iterate through pre_commnads
if [[ "${#pre_commands[@]}" -ne 0 ]]; then
info "Found pre commands..."
# Run each pre command
for pre_command in "${pre_commands[@]}"; do
info "Running \"${pre_command}\":"
eval "${pre_command}"
# Check if pre command ran successfully
if [[ $? -eq 0 ]]; then
success "Pre command \"${pre_command}\" successfully completed!"
else
error "Pre command \"${pre_command}\" failed..."
fi
done
fi
# Set prefix variables for backup
current_action="backup"
current_task=1
total_tasks="${#folders_to_backup[@]}"
# Iterate through "$folders_to_backup"
for folder_to_backup in "${folders_to_backup[@]}"; do
# Check if folder exists
debug "Check if source folder \"${folder_to_backup}\" exists..."
if [[ -d "${folder_to_backup}" ]]; then
# Exist => continue
info "Source folder \"${folder_to_backup}\" exists!"
# Make sure backup destination exists
backup_basename=$(replace_slash_with_dash "${folder_to_backup}")
absolute_backup_destination=$(strip_duplicate_slashes_in_path "${backup_destination}/${backup_basename}")
if [[ ! -d "${absolute_backup_destination}" ]]; then
info "Backup destination folder \"${absolute_backup_destination}\" doesn't exist. Creating..."
mkdir -p "${absolute_backup_destination}"
fi
# Check if backup already exists (to make sure)
if [[ -f "${absolute_backup_destination}/${timestamp}.tar.gz" ]]; then
error "Backup \"${absolute_backup_destination}/${timestamp}.tar.gz\" already exists. Skipping..."
else
# Start backup
info "Starting backup \"${absolute_backup_destination}/${timestamp}.tar.gz\""
tar czf "${absolute_backup_destination}/${timestamp}.tar.gz" -P "${folder_to_backup}" "${tar_exclude_parameters[@]}"
if [[ $? -eq 0 ]]; then
success "Backup \"${absolute_backup_destination}/${timestamp}.tar.gz\" successfully completed!"
else
error "Backup \"${absolute_backup_destination}/${timestamp}.tar.gz\" failed..."
fi
fi
# Remove old backups
if [[ ! -z "${backup_retention}" ]]; then
find "${absolute_backup_destination}/" -maxdepth 1 -mtime "${backup_retention}" -type f -exec rm -rf {} \;
fi
else
# Doesn't exist => skip
error "Folder \"${folder_to_backup}\" doesn't exist. Skipping..."
fi
# Increment $current_task variable
current_task=$((current_task+1))
done
# Set prefix variables for pre-commands
current_action="post-command"
current_task=1
total_tasks="${#post_commands[@]}"
# Iterate through post_commnads
if [[ "${#post_commands[@]}" -ne 0 ]]; then
info "Found post commands..."
# Run each post command
for post_command in "${post_commands[@]}"; do
info "Running \"${post_command}\":"
eval "${post_command}"
# Check if post command ran successfully
if [[ $? -eq 0 ]]; then
success "Post command \"${post_command}\" successfully completed!"
else
error "Post command \"${post_command}\" failed..."
fi
done
fi
# Return exit code
exit 0