Im new to bash scripting, and I want to write a script called unpack, something like this:

unpack [-r] [-v] file [file...]
-v - verbose
-r - recursive - will traverse contents of folders recursively, performing unpack on each.

I need to determine what kind of compression was used and perform unpacking for those compression types.

Assuming file names and extensions could have no meaning - the only way to know what method to use is through the file command. I have 4 unpacking options gunzip, bunzip2, unzip, uncompress

so I wrote a function called execute_unpacking



    for FILE in "${@}"
        local FILE_TYPE=$(file "${FILE}")

        # How to get the compression type of the file?

        case "${FILE_TYPE}" in
            *bzip2) bunzip2 ${RECURSIVE} "${FILE}" ;;
            *gzip) gunzip ${RECURSIVE} "${FILE}" ;;
            *Zip) unzip ${RECURSIVE} ${FILE} ;;
            *compress) uncomprees ${RECURSIVE} ${FILE} ;;
            ?) echo "${FILE} cannot be extarcted" ;;


So based on the $(file ${FILE}) i need to check for Zip, bzip2, compress, gzip

Is this the correct way to do it? (i don't want to use external tools like dtrx )

For example if I have 4 files:

$(file -i archive) => archive: text/plain; charset=us-ascii
$(file -i archive.bz2) => archive.bz2: application/x-bzip2; charset=binary
$(file -i archvive.gz) =>archive.gz: application/x-gzip; charset=binary
$(file -i archive.cmpr) => archive.cmpr: application/x-compress; charset=binary

So i need to assign to the FILE_TYPE variable 4 options gzip,compress,bzip2,txt and then match those pattern accordingly inside of my case statement

When I tried to ./unpack.sh archive.zip Nothing happened unfortantelly.

Thanks in advance for your help!

  • "I don't want to use external tools like dtrx" you're already using external tools like bzip2, gunzip, uncompress, etc. Feb 7, 2022 at 12:03

2 Answers 2



local file_type=$(file -b "${FILE}" | awk '{print $1}')

You can then test for XZ, gzip, etc or whatever it produces.


Just use libarchive bsdtar, which can extract most archive formats (tar, tgz, zip, isos...) by itself:

bsdtar -xf "$any_archive"

(see also additional options such as p/o/S to handle permissions, ownership, sparseness where relevant).

Or libarchive's bsdcat to uncompress most compression formats (gz, xz, bz2)

bsdcat -- "$compressed_file" > "$uncompressed_file"

Note that zip is an archive format, not (only) a compression format. zip archives will typically contain more than one member. bsdcat would just concatenate them. Use bsdtar instead to extract them.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .