morristech
6/29/2019 - 1:01 AM

bash script to extract archives always in a directory

bash script to extract archives always in a directory

#!/usr/bin/env bash

# Unpack archive safely (means always in its own directory
#
# @param 1 - name and path of archive to extract
function unpack()
{
	local ARCHIVE=$1
	local TMP=".unpack-$USER-$$"
	local NAME=${ARCHIVE##*/}
	NAME=${NAME%%.*}

	# make path absolute
	[ "${ARCHIVE:0:1}" != '/' ] &&
		ARCHIVE="$PWD/$ARCHIVE"

	[ -f "$ARCHIVE" ] || {
		echo "error: $ARCHIVE not found" >&2
		return 1
	}

	# ensure destination directory does not exist yet
	{
		local BASE=$NAME
		local N=2

		while [ -d "$NAME" ]
		do
			NAME="$BASE-$N"
			(( ++N ))
		done
	}

	mkdir "$TMP" || {
		echo 'error: cannot create temporary directory' >&2
		return 1
	}

	cd "$TMP" || {
		echo 'error: cannot change into temporary directory' >&2
		return 1
	}

	case "$ARCHIVE" in
		*.[Zz][Ii][Pp])
			unzip "$ARCHIVE"
			;;
		*.[Rr][Aa][Rr])
			unrar x "$ARCHIVE"
			;;
		*.[Tt][Bb][Zz]2|*.[Tt][Aa][Rr].[Bb][Zz]2)
			tar xjvf "$ARCHIVE"
			;;
		*.[Tt][Gg][Zz]|*.[Tt][Aa][Rr].[Gg][Zz])
			tar xzvf "$ARCHIVE"
			;;
		*.[Gg][Zz])
			gzip -d "$ARCHIVE"
			;;
		*.[Bb][Zz][Ii][Pp]2|*.[Bb][Zz]2)
			bzip2 -d "$ARCHIVE"
			;;
		*.[Xx][Zz])
			tar xf "$ARCHIVE"
			;;
		*)
			echo 'error: unknown archive' >&2
			;;
	esac

	# move into place
	{
		local F FILES=0

		for F in *
		do
			[ -e "$F" ] || continue
			(( ++FILES ))
		done

		cd ..

		if (( FILES == 0 ))
		then
			rmdir "$TMP"
		elif (( FILES == 1 ))
		then
			mv -i "$TMP/"* .
			rmdir "$TMP"
		else
			mv -i "$TMP" "$NAME"
		fi
	}

	return 0
}

for A
do
	unpack "$A" || exit 1
done