Skip to content

Instantly share code, notes, and snippets.

@daladim
Last active September 8, 2020 13:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daladim/5dba469af1717b21cdc1886e522c4f49 to your computer and use it in GitHub Desktop.
Save daladim/5dba469af1717b21cdc1886e522c4f49 to your computer and use it in GitHub Desktop.
UNTAR (Ultimate Nice Tool making Archives Right)
#!/bin/bash
# UNTAR - Ultimate Nice Tool making Archives Right
# This tool calls tar (or other archiving binaries) with the right arguments -- you no longer need to remember them
# To extract: run 'untar mytarball.<whatever>', this tool will infer the right arguments
# To compress: run 'mytar mytarball.<whatever> contents', this tool will infer the right arguments
# See the usage for extra possible options
#
# To install:
# Copy this script somewhere in your $PATH (and make it executable)
# Also create a link (in your $PATH) called 'mytar' pointing to this script
# This way, this script will infer the action to perform (compressing or extracting) from the name it was invoked with.
#
# This script is hosted (and possibly updated) on https://gist.github.com/daladim/5dba469af1717b21cdc1886e522c4f49
function usage {
echo "UNTAR - Ultimate Nice Tool making Archives Right"
echo "This tool calls tar (or other archiving binaries) with the right arguments -- you no longer need to remember them"
echo "Call as 'mytar' to compress, call as 'untar' to decompress"
echo ""
if [ "${calledAs}" == "untar" ]; then
echo -e " ${calledAs} [-v] [-p archive_password] ballname.tar.[gz|bz2|whatever] [destination]"
echo -e " This extracts all items from the archive"
else
echo -e " ${calledAs} [-v] [-p archive_password] ballname.tar.[gz|bz2|whatever] items_to_compress"
echo -e " This compresses the items_to_compress into a newly created archive"
fi
echo -e ""
echo -e "Options:"
echo -e " -v\tOnly show the command"
echo -e " -p\tPassword-protect the archive (only for supported formats)"
echo -e " \tNote that passing password in a command line is insecure, since it may be read by other users"
echo ""
}
calledAs=$(basename "$0")
if [ "$1" == "-h" -o "$1" == "--help" ]; then
usage $@
exit 0
fi
if [ "$#" -lt 1 ]; then
usage $@
exit 1
fi
# Parse arguments
COMPRESS="y"
if [ "$calledAs" == "untar" ]; then
COMPRESS="n"
fi
ONLY_PRINT_COMMAND="n"
ARCHIVE_PASSWORD=""
while [ "$#" -gt 0 ]; do
if [ "$1" == "-v" ]; then
ONLY_PRINT_COMMAND="y"
shift
elif [ "$1" == "-p" ]; then
shift
ARCHIVE_PASSWORD="$1"
shift
else
break
fi
done
ballname="$1"
shift
if [ "$COMPRESS" == "n" ]; then
if [ "$#" -ge 1 ]; then
destination="$1"
destargs_tar="-C"
destargs_zip="-d"
if [ "$ONLY_PRINT_COMMAND" == "n" ]; then
mkdir -p "$1"
fi
fi
fi
# Inferring archive type
bn=$(basename "$ballname")
extension="${bn##*.}"
TYPE="unknown"
if [ "$extension" == "bz2" ]; then
TYPE="bz2"
elif [ "$extension" == "gz" ]; then
# We should distinguish .tar.gz and .gz here
if [[ "$bn" == *.tar.gz ]]; then
TYPE="gz"
fi
elif [ "$extension" == "tgz" ]; then
TYPE="gz"
elif [ "$extension" == "lzma" ]; then
TYPE="lzma"
elif [ "$extension" == "xz" ]; then
TYPE="xz"
elif [ "$extension" == "tar" ]; then
TYPE="tar"
elif [ "$extension" == "deb" -o "$extension" == "ipk" ]; then
TYPE="deb"
elif [ "$extension" == "a" ]; then
TYPE="ar"
elif [ "$extension" == "7z" ]; then
TYPE="7zip"
elif [ "$extension" == "zip" ]; then
TYPE="zip"
fi
if [ "$TYPE" == "unknown" ]; then
echo "'$bn' does not look like an archive." >&2
exit 3
fi
# Unless later overridden, these are the defaults
binary="tar"
args=""
passwdargs=""
password=""
destargs="$destargs_tar"
if [ "$TYPE" == "gz" ]; then
if [ "$COMPRESS" == "y" ]; then
args="czf"
else
args="xzf"
fi
elif [ "$TYPE" == "bz2" ]; then
if [ "$COMPRESS" == "y" ]; then
args="cjf"
else
args="xjf"
fi
elif [ "$TYPE" == "lzma" ]; then
# Note: LZMA and XZ are actually the same algorithm (which may or may not be generated by the same implementation)
if [ "$COMPRESS" == "y" ]; then
args="--lzma -cpf"
else
args="--lzma -xf"
fi
elif [ "$TYPE" == "xz" ]; then
if [ "$COMPRESS" == "y" ]; then
args="cpJf"
else
args="xJf"
fi
elif [ "$TYPE" == "tar" ]; then
if [ "$COMPRESS" == "y" ]; then
args="cf"
else
args="xf"
fi
elif [ "$TYPE" == "deb" -o "$TYPE" == "ar" ]; then
if [ "$COMPRESS" == "y" ]; then
binary="ar"
args="r"
else
binary="ar"
args="x"
fi
elif [ "$TYPE" == "7zip" ]; then
if [ "$COMPRESS" == "y" ]; then
args="a"
else
args="x"
fi
# 7 zip binary can have multiple names...
if [ -x "$(command -v 7z)" ]; then
binary="7z"
else
echo "7zip is not installed. To install it, prefer the package p7zip-full over p7zip" >&2
exit 2
fi
# ...and archives may be password-protected
if [ -n "$ARCHIVE_PASSWORD" ]; then
passwdargs="-mhe=on -p"
echo "Warning: all versions of 7zip binaries do not support password, check that your archive is really protected!"
fi
elif [ "$TYPE" == "zip" ]; then
if [ ! -x "$(command -v zip)" ]; then
echo "zip is not installed." >&2
exit 2
fi
if [ "$COMPRESS" == "y" ]; then
args="-r"
binary="zip"
else
args=""
binary="unzip"
destargs="$destargs_zip"
fi
if [ -n "$ARCHIVE_PASSWORD" ]; then
passwdargs="-P "
fi
fi
# {$var:+"$var"} properly quotes for spaces, yet does not expand to anything if it is empty
if [ "$ONLY_PRINT_COMMAND" == "y" ]; then
echo -e "\033[1m$binary $args\033[0m" \
${passwdargs}${ARCHIVE_PASSWORD:+"$ARCHIVE_PASSWORD"} \
"$ballname" $destargs ${destination:+"$destination"} "$@"
else
$binary $args \
${passwdargs}${ARCHIVE_PASSWORD:+"$ARCHIVE_PASSWORD"} \
"$ballname" $destargs ${destination:+"$destination"} "$@"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment