130 lines
2.8 KiB
Bash
Executable file
130 lines
2.8 KiB
Bash
Executable file
#!/usr/bin/env sh
|
|
|
|
# printc(args, description)
|
|
# Helper function to properly format text
|
|
printc() {
|
|
args="$1"
|
|
cmd="$2"
|
|
printf ' %s' "$1"
|
|
yes '' | head -n "$((20-${#args}))" | tr \\n ' '
|
|
printf '%s' "$cmd"
|
|
echo
|
|
}
|
|
|
|
# usage()
|
|
# Display usage information
|
|
usage() {
|
|
echo "usage: tartar [-0..9] [--level N] [--format F] DIR"
|
|
echo "Creates a compressed tape archive of every subdirectory in a given directory"
|
|
echo
|
|
echo "positional arguments:"
|
|
printc "DIR" "the directory to archive"
|
|
echo
|
|
echo "parameters:"
|
|
printc "-f, --format" "the compression format to use. default: xz"
|
|
printf '%44s %s\n' "options: gzip, xz"
|
|
printc "-0..-9, --level" "the level of compression to use: default 6"
|
|
echo
|
|
echo "environment variables:"
|
|
printc "ARCHIVE_DIR" "same as positional argument DIR"
|
|
printc "COMPRESSION_FORMAT" "same as --format"
|
|
printc "COMPRESSION_LEVEL" "same as --level"
|
|
}
|
|
|
|
includes() {
|
|
test="$1"
|
|
shift
|
|
for x in "$@"; do
|
|
if test "$test" = "$x"; then
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
FORMATS="gzip xz"
|
|
LEVELS="0 1 2 3 4 5 6 7 8 9"
|
|
|
|
COMPRESSION_FORMAT="xz"
|
|
COMPRESSION_LEVEL="-6"
|
|
|
|
set_format() {
|
|
if includes "$1" "$FORMATS"; then
|
|
COMPRESSION_FORMAT="$1"
|
|
fi
|
|
}
|
|
|
|
set_level() {
|
|
if includes "$1" "$LEVELS"; then
|
|
COMPRESSION_LEVEL="-$1"
|
|
fi
|
|
}
|
|
|
|
parse_args() {
|
|
POSITIONAL_ARGS=""
|
|
|
|
# parse args
|
|
while [ $# -gt 0 ]; do
|
|
case $1 in
|
|
-f|--format)
|
|
set_format "$2"
|
|
shift
|
|
shift
|
|
;;
|
|
--level)
|
|
set_level "$2"
|
|
shift
|
|
shift
|
|
;;
|
|
-0|-1|-2|-3|-4|-5|-6|-7|-8|-9)
|
|
COMPRESSION_LEVEL="$1"
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
POSITIONAL_ARGS="$POSITIONAL_ARGS $1"
|
|
shift # past argument
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# drop the first space
|
|
POSITIONAL_ARGS=$( echo "$POSITIONAL_ARGS" | tail -c +2 )
|
|
}
|
|
|
|
can_archive() {
|
|
if test ! -f "${1}/backup.done"; then
|
|
echo "skipping $1; it is either incomplete or corrupted"
|
|
return 1
|
|
fi
|
|
|
|
if test ! -f "${1}/compression.done" || \
|
|
test ! -f "${1}.tar.xz" || \
|
|
! sha1sum -sc "${1}/compression.done"; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
parse_args "$@"
|
|
|
|
# get the first positional argument, trim whitespace
|
|
dir=$( echo "$POSITIONAL_ARGS" | cut -d' ' -f1 | xargs )
|
|
dir=${dir:-"$ARCHIVE_DIR"}
|
|
|
|
|
|
cd "$dir" || exit 1
|
|
|
|
for dir in ./*/; do
|
|
dir="${dir%*/}"
|
|
if can_archive "$dir"; then
|
|
fname="$(basename $dir).tar.xz"
|
|
tar cv --exclude='*.done' "$dir" | "$COMPRESSION_FORMAT" "$COMPRESSION_LEVEL" > "$fname"
|
|
sha1sum "$fname" > "${dir}/compression.done"
|
|
fi
|
|
done
|
|
|