174 lines
5.2 KiB
Bash
174 lines
5.2 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# common.sh - common functions.
|
|
# Copyright (c) 2022 ge <https://nixhacks.net/>
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
log() {
|
|
# Logger. Write message to __log_file.
|
|
#
|
|
# Usage: log [-p] MESSAGE
|
|
#
|
|
# Can read from STDIN. Removes ANSI escape codes from log message.
|
|
# Echo message to STDOUT with '-p' option.
|
|
|
|
local message
|
|
local print
|
|
|
|
# Read message from STDIN if args not passed.
|
|
[[ ! -t 0 ]] || [[ "$#" == 0 ]] && message="$(cat <&0)"
|
|
|
|
# Set log date format
|
|
[ "$log_date_fmt" ] || log_date_fmt="$__log_date_fmt"
|
|
|
|
while (( "$#" )); do
|
|
case "$1" in
|
|
-p) print=1; shift;;
|
|
-) message="$(cat <&0)"; shift "$#";;
|
|
*) message="$*"; shift "$#";;
|
|
esac
|
|
done
|
|
|
|
[[ "$print" == 1 ]] && echo -e "$message"
|
|
|
|
while read -r line; do
|
|
if [[ "$line" ]]; then
|
|
printf '[%s] %s\n' "$(date +"$log_date_fmt")" "$line" >> "$__log_file"
|
|
fi
|
|
done <<< "$(sed -r 's/\x1B\[(([0-9]+)(;[0-9]+)*)?[m,K,H,f,J]//g' <<< "$message")"
|
|
}
|
|
|
|
err() {
|
|
# Handle errors. Print errors to STDERR, log, process
|
|
# and exit from script.
|
|
#
|
|
# Usage: err [-eao] MESSAGE
|
|
|
|
local message
|
|
local errexit
|
|
local errappend
|
|
local onerr
|
|
|
|
[[ ! -t 0 ]] || [[ "$#" == 0 ]] && message="$(cat <&0)"
|
|
|
|
# Split combined short options, e.g. '-abc' to '-a' '-b' '-c'
|
|
for args in "$@"; do
|
|
shift
|
|
case "$args" in
|
|
-*)
|
|
args="$(echo "${args:1}" | grep -o . | xargs -I {} echo -n '-{} ')"
|
|
set -- "$@" $args;;
|
|
*)
|
|
set -- "$@" "$args";; # save positional arguments
|
|
esac
|
|
done
|
|
|
|
while (( "$#" )); do
|
|
case "$1" in
|
|
-e) errexit=1; shift;;
|
|
-a) errappend=1; shift;;
|
|
-o) onerr=1; shift;;
|
|
-) message="$(cat <&0)"; shift "$#";;
|
|
*) message="$*"; shift "$#";;
|
|
esac
|
|
done
|
|
|
|
log "$message"
|
|
echo -e "$message" >&2
|
|
[ "$errappend" ] && errors+=("$message")
|
|
|
|
# Run user defined function on_error()
|
|
if [ "$onerr" ]; then
|
|
if is_function_set on_error; then
|
|
echo -e "Run \e[1mon_error()\e[0m" | log -p
|
|
on_error
|
|
fi
|
|
fi
|
|
|
|
# Exit
|
|
if [ "$errexit" ]; then
|
|
# Count errors for backup recap
|
|
__errors_count="$(cat $__errors_file)"
|
|
((__errors_count++)) || true
|
|
echo $__errors_count > "$__errors_file"
|
|
|
|
log -p "Backup ERROR: Exiting with previous errors" >&2; exit 1
|
|
fi
|
|
}
|
|
|
|
try() {
|
|
# Commands wrapper for error handling
|
|
#
|
|
# Usage: try COMMAND
|
|
|
|
if eval "$@" 2>> "$__log_file"; then
|
|
return 0 # Success
|
|
else
|
|
# Count errors
|
|
err -a "Error: Something went wrong when executing command:"
|
|
err -a " $*"
|
|
err -aeo "Check $__log_file log for details."
|
|
fi
|
|
}
|
|
|
|
is_installed() {
|
|
# Check if the program is installed.
|
|
# See good answer: https://stackoverflow.com/a/677212
|
|
#
|
|
# Usage: is_installed COMMAND
|
|
|
|
if ! command -v "$1" >/dev/null 2>&1; then
|
|
echo "Error: Command $1 not found." \
|
|
"Please install $1 or check your PATH if it's actually installed." >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
is_function_set() {
|
|
# Test function is set or not. Return exit code.
|
|
# Useful with 'if' statement.
|
|
#
|
|
# Usage: is_function_set FUNCTION
|
|
|
|
declare -F -- "$1" > /dev/null
|
|
return "$?"
|
|
}
|
|
|
|
set_compression() {
|
|
# Set compr_util and file_ext by name.
|
|
|
|
# Select compression utility and set filename extension.
|
|
# Refference: https://www.gnu.org/software/tar/manual/html_node/gzip.html
|
|
case "$1" in
|
|
gzip|gz) file_ext='.gz'; compr_util='gzip';;
|
|
tgz) file_ext='.gz'; compr_util='gzip';;
|
|
taz) file_ext='.gz'; compr_util='gzip';;
|
|
compress|Z) file_ext='.Z'; compr_util='compress';;
|
|
taZ) file_ext='.Z'; compr_util='compress';;
|
|
bzip2|bz2) file_ext='.bz2'; compr_util='bzip2';;
|
|
tz2) file_ext='.bz2'; compr_util='bzip2';;
|
|
tbz2) file_ext='.bz2'; compr_util='bzip2';;
|
|
tbz) file_ext='.bz2'; compr_util='bzip2';;
|
|
lzip|lz) file_ext='.lz'; compr_util='lzip';;
|
|
lzma) file_ext='.lzma'; compr_util='lzma';;
|
|
tlz) file_ext='.lzma'; compr_util='lzma';;
|
|
lzop|lzo) file_ext='.lzop'; compr_util='lzop';;
|
|
xz) file_ext='.xz'; compr_util='xz';;
|
|
zstd|zst) file_ext='.zst'; compr_util='zstd';;
|
|
tzst) file_ext='.zst'; compr_util='zstd';;
|
|
*) file_ext=''; compr_util='';; # No compression
|
|
esac
|
|
}
|