-
-
Save mubeeniqbal/81fd74d5e8cf522c780f to your computer and use it in GitHub Desktop.
Runs a command wrapped with snapper pre-post snapshots for btrfs subvolumes. File path: /usr/local/bin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# | |
# Runs a command wrapped with snapper pre-post snapshots for btrfs subvolumes. | |
# Usage: snp [-c config1,config2,...] <command> | |
# Constants | |
readonly LOG_PATH='/var/local/log/snp' | |
readonly DATE="$(date +'%Y-%m-%d-%H%M%S')" | |
readonly LOG_FILE="${LOG_PATH}/snp-${DATE}.log" | |
####################################### | |
# Print out error messages to STDERR. | |
# Globals: | |
# None | |
# Arguments: | |
# Error | |
# Returns: | |
# None | |
####################################### | |
err() { | |
echo "[$(date +'%Y-%m-%d %H:%M:%S%z')] error: $@" 1>&2 | |
} | |
####################################### | |
# Log STDOUT and STDERR. | |
# Reference: http://stackoverflow.com/questions/3173131/redirect-copy-of-stdout-to-log-file-from-within-bash-script-itself | |
# Globals: | |
# None | |
# Arguments: | |
# Path to log file | |
# Returns: | |
# None | |
####################################### | |
log_stdout_stderr() { | |
exec > >(tee -a "$@") | |
exec 2> >(tee -a "$@" >&2) | |
} | |
# TODO(mubeeniqbal): Use of eval considered dangerous. Find an alternative to all eval commands. | |
main() { | |
if [[ "${EUID}" -ne 0 ]]; then | |
err 'snp: you cannot perform this operation unless you are root: Permission denied' | |
exit 1 | |
fi | |
if [[ ! -d "${LOG_PATH}" ]]; then | |
mkdir -vp "${LOG_PATH}" || return | |
fi | |
log_stdout_stderr "${LOG_FILE}" | |
# Snapper configs array. | |
local -a CONFIGS=('root') | |
# Populate the array if configs are provided in arguments. | |
if [[ "$1" = '-c' ]]; then | |
shift | |
CONFIGS=(${1//,/ }) | |
shift | |
fi | |
# Make configs array constant. | |
readonly CONFIGS | |
local -ri CONFIG_COUNT="${#CONFIGS[@]}" | |
# Save command to wrap with pre-post snapshots. | |
local -r CMD="$@" | |
# Declare local snapshot numbers array. | |
local -a numbers | |
local snapper_cmd | |
echo '> Creating pre snapshots.' | |
local -i i | |
# Create pre snapshots. | |
for ((i=0; i<"${CONFIG_COUNT}"; ++i)); do | |
snapper_cmd="snapper --config=${CONFIGS[${i}]} create --type=pre --cleanup-algorithm=number --print-number --description=\"command: ${CMD}\"" | |
echo "> Running command: ${snapper_cmd}" | |
numbers["${i}"]="$(eval "${snapper_cmd}")" || return | |
echo "> Snapshot created: config:${CONFIGS[${i}]}, type:pre, number:${numbers[${i}]}" | |
done | |
# Run wrapped command. | |
echo '> ---------------------------------------------------------------------' | |
echo "> Running command: ${CMD}" | |
eval "${CMD}" | |
echo '> ---------------------------------------------------------------------' | |
echo '> Creating post snapshots.' | |
# Create post snapshots. | |
for ((i=0; i<"${CONFIG_COUNT}"; ++i)); do | |
snapper_cmd="snapper --config=${CONFIGS[${i}]} create --type=post --cleanup-algorithm=number --print-number --description=\"command: ${CMD}\" --pre-number=${numbers[${i}]}" | |
echo "> Running command: ${snapper_cmd}" | |
numbers["${i}"]="$(eval "${snapper_cmd}")" || return | |
echo "> Snapshot created: config:${CONFIGS[${i}]}, type:post, number:${numbers[${i}]}" | |
done | |
exit 0 | |
} | |
main "$@" |
-c
is exactly what I was looking for. Thank you!
Why do you always deny unless root? My .snapshots
directory is accessible to me. (man snapper #PERMISSIONS)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Why is that so? What effect does (( )) have over [[ ]]?