ambevar-dotfiles/.scripts/archive

109 lines
2.5 KiB
Bash
Executable File

#!/bin/sh
_usage () {
cat <<EOF
Usage: ${1##*/} [-m METHOD] [-v] FILES|FOLDERS
Create an archive in current folder from a single or multiples
files/folders. Each input entry will be at archive root (no absolute path is
used). If only one file/folder is given as input, then the archive is named
after this input. Otherwise it is named after current PWD.
-h: Display this help.
-i: The archive is created without owner/group information. (GNU tar only.)
-m: Choose compression method.
* gz: gzip (default).
* none: Simple tar archive.
* xz: LZMA.
-s: Archive each input entry an individual file.
-v: Exclude VCS data. (GNU tar only.)
EOF
}
OUTPATH="$PWD"
ARCEXT=".gz"
ARCOPT="z"
OPTIONS=""
OPT_SPLIT=false
while getopts ":him:sv" opt; do
case $opt in
h)
_usage "$0"
exit 1 ;;
i)
OPTIONS="$OPTIONS --owner=root --group=root --numeric-owner" ;;
m)
[ "$OPTARG" = "gz" ] && ARCEXT=".gz" && ARCOPT="z"
[ "$OPTARG" = "xz" ] && ARCEXT=".xz" && ARCOPT="J"
[ "$OPTARG" = "none" ] && ARCEXT="" && ARCOPT=""
;;
s)
OPT_SPLIT=true ;;
v)
OPTIONS="$OPTIONS --exclude-vcs" ;;
\?)
_usage "$0"
exit 1 ;;
esac
done
shift $(($OPTIND - 1))
if [ $# -eq 0 ]; then
_usage "$0"
exit 1
fi
## We need 'realpath' since we need to work on the real path for the input
## files/folders and the archive location. Otherwise we could have troubles with
## circular symlinks and so on.
if ! command -v realpath >/dev/null 2>&1; then
echo >&2 "'realpath' not found in PATH. Exiting."
exit 1
fi
_archive () {
## Only one input entry: use it as base name for the archive.
if [ $# -eq 1 ]; then
REALPATH="$(realpath "$1")"
OUTFILE="${REALPATH##*/}-$(date +%F-%H%M%S).tar${ARCEXT}"
else
OUTFILE="${PWD##*/}-$(date +%F-%H%M%S).tar${ARCEXT}"
fi
REALPWD="$(realpath "$PWD")"
for i; do
REALPATH="$(realpath "$i")"
## Check if one of the arguments is current folder. We need to make sure the
## archive is not created in an input folder, otherwise it will include
## itself.
if [ "$REALPATH" = "$REALPWD" ]; then
OUTPATH="$(realpath "$REALPWD/..")"
break
fi
done
if [ ! -w "$OUTPATH" ]; then
echo "[$OUTPATH] is not writable. Exiting."
return
fi
echo "==> [$OUTPATH/$OUTFILE]"
for i; do
REALPATH="$(realpath "$i")"
echo "${REALPATH}" >&2
echo "-C '${REALPATH%/*}'"
echo "${REALPATH##*/}"
done | tar $OPTIONS -${ARCOPT}cf "$OUTPATH/$OUTFILE" -T -
}
if $OPT_SPLIT; then
for j ; do
_archive "$j"
done
else
_archive "$@"
fi