Home / Alt manpages / unzip(1)

  • unzip(1)
  • User command
  • linux

Safely inspect and extract ZIP archives with unzip

You will inspect a ZIP archive, verify its compressed data, and extract selected files into a directory you control. The examples use the installed Info-ZIP unzip 6.00 command supplied by the Ubuntu unzip package, version 6.0-28ubuntu4.1. Allow about ten minutes for a small archive, longer if you need to review many members.

You need a shell, a readable archive, and write permission in the destination. Ordinary extraction does not need sudo. Using elevated privileges can create root-owned files and makes mistakes harder to undo.

1. Check the command and archive

Confirm which executable your shell will run and record its version. This matters when a script depends on a particular option or on support such as Zip64 or encrypted entries.

$ command -v unzip
/home/linuxbrew/.linuxbrew/bin/unzip
$ unzip -v | sed -n '1,24p'
UnZip 6.00 of 20 April 2009, by Debian.
...
        ZIP64_SUPPORT (archives using Zip64 for large files)
        [decryption, version 2.11 of 05 Jan 2007]

The exact path and build details can differ. The useful checks are that the command exists and that its reported capabilities match what you need. Then check the input without extracting anything:

$ test -r /path/to/archive.zip && echo "archive is readable"
archive is readable
$ unzip -l /path/to/archive.zip

-l lists member names, uncompressed sizes, timestamps and totals. Read this list before extraction. It can reveal an unexpected top-level directory, a destination filename you already use, or a suspiciously large expansion.

Checkpoint

You know the exact archive path, have reviewed its member names, and have chosen a destination that is not a directory containing irreplaceable files.

2. Test the archive before writing files

Use -t to expand each selected member in memory and compare its CRC with the stored value. Add -q when you want a compact result:

$ unzip -tq /path/to/archive.zip
No errors detected in compressed data of /path/to/archive.zip.
$ printf 'test exit status: %s\n' "$?"
test exit status: 0

A zero status means this installed command found no errors or warnings. A status of 1 is a warning, while statuses such as 2 or 3 indicate ZIP format errors. Status 9 means an archive was not found, and status 11 means no matching members were found. Check the command's own output as well as the number: a test does not tell you whether extracted content is trustworthy for your particular purpose.

To test every ZIP in the current directory, quote the wildcard so the shell does not pass an empty or changing list unexpectedly:

$ unzip -tq -- '*.zip'

The archive argument accepts a filename wildcard, but a wildcard in the path itself is not handled the same way. Quoting is also essential when selecting members by wildcard later.

3. Extract into a new destination

Create a fresh destination and extract there with -d. The default destination is the current directory, so being explicit prevents the common mistake of unpacking into whatever directory the shell happened to be using.

$ mkdir -p /tmp/archive-review
$ unzip /path/to/archive.zip -d /tmp/archive-review
Archive:  /path/to/archive.zip
  inflating: /tmp/archive-review/readme.txt
  extracting: /tmp/archive-review/notes.txt
$ find /tmp/archive-review -type f -print

The archive's directory structure is recreated below the destination. Verify the result before moving anything into a permanent location:

$ find /tmp/archive-review -type f -printf '%P\n' | sort
notes.txt
readme.txt
$ unzip -tq /path/to/archive.zip
No errors detected in compressed data of /path/to/archive.zip.

This example changes state by creating files. To undo it after you have finished inspecting the contents, remove only the dedicated review directory, after checking its path carefully:

$ find /tmp/archive-review -mindepth 1 -maxdepth 1 -print
$ rm -r /tmp/archive-review

Do not substitute a broad path for the review directory. If the archive contains symlinks or files with surprising names, inspect them before copying the extracted tree elsewhere.

4. Select members and flatten paths

Put member patterns after the archive name. Quote them so the shell passes the pattern to unzip, which then matches archive members:

$ mkdir -p /tmp/text-review
$ unzip /path/to/archive.zip '*.txt' -d /tmp/text-review

The pattern matches names in the archive, not arbitrary files already on disk. To exclude a member pattern, use -x:

$ unzip /path/to/archive.zip '*.txt' -x 'private/*' -d /tmp/text-review

Use -j only when you deliberately want to discard directory paths and place matching files directly in the destination:

$ mkdir -p /tmp/flat-review
$ unzip -j /path/to/archive.zip 'reports/*.csv' -d /tmp/flat-review

Flattening can create name collisions. Two different archive paths can both become summary.csv, and the usual overwrite rules then apply. Prefer the normal directory structure unless a flat directory is part of the requirement.

5. Protect existing files

By default, unzip asks before overwriting an existing file. For unattended or review-first work, -n skips existing files without asking:

$ unzip -n /path/to/archive.zip -d /tmp/archive-review

Warning

-o overwrites existing files without prompting. It is useful in a controlled update, but it can destroy local edits or replace a file with an archive member you did not inspect. Do not add it just to silence a prompt.

If you intend to replace files, make a backup or extract into a new directory first. There is no general undo operation inside unzip; recovery depends on your backup, version control or the original archive.

6. Handle passwords and failures

For an encrypted member, run normal extraction and let unzip prompt without echoing the password:

$ unzip /path/to/encrypted.zip -d /tmp/archive-review
Archive:  /path/to/encrypted.zip
   skipping: secret.txt             need PK compat. v5.1 (can do v2.0)
   [enter password when prompted]

The exact prompt and diagnostic depend on the archive. Do not use -P PASSWORD in a shell command or script: the password can be exposed through process listings, shell history or logs. The installed build reports decryption support in unzip -v, but standard ZIP encryption is not a substitute for modern encryption when confidentiality matters.

If extraction fails, keep the original archive and inspect the status. A full disk can produce status 50, an interrupted archive can produce status 51, and unsupported compression or decryption can produce status 81. Remove only incomplete files in the dedicated destination, or discard that destination and start again after fixing the cause.

Done means

  • You confirmed the installed Info-ZIP version and relevant build capabilities.
  • You listed the archive and tested its compressed data before extraction.
  • You extracted into an explicit, reviewable destination with ordinary user privileges.
  • You quoted member patterns and used exclusions only where their effect was clear.
  • You avoided silent overwrites and never placed a plaintext password in the command line.
  • You know which destination can be removed if the extraction needs to be discarded.