zip Command: Compress Folders, Extract with unzip, and Compression Options

Test environmentRHEL familyAlmaLinux 9.8root accountChecked 2026-11-05
Compression · archive commandszipunzipLocation/usr/bin/zip
Compressing folders and extracting with unzip

The zip command bundles files and folders on Linux into a single compressed zip file, and unzip is the companion command for extracting it. On an AlmaLinux 9 server, compressing a website folder with zip -r shrank 35,825 bytes to 4,158 bytes, and unzip -O fixed the garbled file names in a zip file made on Windows.

The output below comes from a working folder on an AlmaLinux 9.8 server, run as root, with times in UTC. The site folder and note files that were compressed are sample files made for the test. The zip made on Windows was reproduced with a test file whose file names were stored in CP949.

1️⃣ How to use the zip command

  • ↪️ Compressing files and folders (-r)

After zip, write the name of the new zip file first, then list the files to put in it. The command below compresses two files, readme.txt and memo.txt, into a single notes.zip.

zip notes.zip readme.txt memo.txt
  adding: readme.txt (deflated 92%)
  adding: memo.txt (stored 0%)

The [deflated 92%] at the end of a line is how much smaller the file became compared with its original size. The [stored 0%] on the line for the 71-byte memo.txt means the file was stored at its original size without compression.

To compress a folder, add -r. If you give only the folder name without -r, the archive holds just the folder entry site/ and none of the files inside it.

zip nodir.zip site
  adding: site/ (stored 0%)

The site folder to compress has three subfolders and six files, as shown below.

site/
css/
style.css
js/
app.js
logs/
access.log
index.html
about.html
.htaccess

With -r, all ten entries go in: the subfolders, the files inside them, and even .htaccess, whose name starts with a dot.

zip -r site.zip site
  adding: site/ (stored 0%)
  adding: site/css/ (stored 0%)
  adding: site/css/style.css (deflated 93%)
  adding: site/js/ (stored 0%)
  adding: site/js/app.js (deflated 87%)
  adding: site/logs/ (stored 0%)
  adding: site/logs/access.log (deflated 94%)
  adding: site/index.html (deflated 91%)
  adding: site/about.html (deflated 87%)
  adding: site/.htaccess (deflated 9%)

To see what a finished zip file contains without extracting it, use unzip -l. The stored files added up to 35,825 bytes, while ls -l showed site.zip at 4,158 bytes.

unzip -l site.zip
Archive:  site.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  10-28-2026 22:10   site/
        0  10-28-2026 22:10   site/css/
     4431  10-28-2026 22:10   site/css/style.css
        0  10-28-2026 22:10   site/js/
     1882  10-28-2026 22:10   site/js/app.js
        0  10-28-2026 22:10   site/logs/
    24134  10-28-2026 22:10   site/logs/access.log
     3723  10-28-2026 22:10   site/index.html
     1612  10-28-2026 22:10   site/about.html
       43  10-28-2026 22:10   site/.htaccess
---------                     -------
    35825                     10 files
ls -l site.zip
-rw-r--r-- 1 root root 4158 Oct 28 23:05 site.zip

2️⃣ zip command options

  • ↪️ -x, -u, -d, compression level, -e

Among the zip command options, -x leaves out files that match a pattern. Specifying [site/logs/*] to skip the log folder leaves out the logs folder and access.log, so only eight entries go in.

zip -r site-nolog.zip site -x 'site/logs/*'
  adding: site/ (stored 0%)
  adding: site/css/ (stored 0%)
  adding: site/css/style.css (deflated 93%)
  adding: site/js/ (stored 0%)
  adding: site/js/app.js (deflated 87%)
  adding: site/index.html (deflated 91%)
  adding: site/about.html (deflated 87%)
  adding: site/.htaccess (deflated 9%)

Wrap the pattern in single quotes so the shell does not expand [*] into file names first. For the same purpose, the official manual gives an example with a backslash in front of [*].

-u puts back only the files that changed after the zip file was made. After adding one line to the end of index.html, running with -ru re-adds just that one file as [updating].

zip -ru site.zip site
updating: site/index.html (deflated 90%)

Running the same command again with nothing changed printed nothing, and the exit code was 12. In the official manual, 12 means zip has nothing to do.

zip -ru site.zip site; echo $?
12

To delete entries inside a zip file, use -d. Specifying [site/logs/*] removes the logs folder entry and access.log from site.zip.

zip -d site.zip 'site/logs/*'
deleting: site/logs/
deleting: site/logs/access.log

The numbers -0 to -9 set the compression level, and the default is -6 according to the official manual. The same site folder was compressed three times with -q, which prints nothing, to compare sizes. Because one line had been added to index.html during the -u test, the original files now total 35,875 bytes.

zip -qr -0 level0.zip site
zip -qr level6.zip site
zip -qr -9 level9.zip site
ls -l level*.zip
-rw-r--r-- 1 root root 37433 Oct 28 23:05 level0.zip
-rw-r--r-- 1 root root  4179 Oct 28 23:05 level6.zip
-rw-r--r-- 1 root root  3874 Oct 28 23:05 level9.zip
Compression levelzip file sizevs. original total
Original file total35,875 bytes100%
-0 (no compression)37,433 bytes104.3%
-6 (default)4,179 bytes11.6%
-9 (maximum compression)3,874 bytes10.8%

The 37,433 bytes made with -0 were larger than the 35,875-byte original total. That is the uncompressed data plus 1,558 bytes of header information, such as file names and times, attached to each entry. -9 came out 305 bytes smaller than the default, and the whole difference came from the largest file, access.log.

To set a password, add -e. You type the password twice, and the characters you type do not appear on the screen.

zip -e secret.zip memo.txt
Enter password:
Verify password:
  adding: memo.txt (stored 0%)

Even secret.zip, made with -e, showed its file names, sizes and dates under unzip -l without a password. Only the file contents are encrypted, so it does not suit material whose file names must stay hidden too.

unzip -l secret.zip
Archive:  secret.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
       71  10-28-2026 22:10   memo.txt
---------                     -------
       71                     1 file

-P, which puts the password right on the command line, is an option the official manual warns is insecure, because other users on the same server can see running commands. The manual also describes zip's standard encryption itself as relatively weak.

When extracting a zip made with -e, unzip asks for the password for each file, and the file is extracted once you enter it correctly.

unzip secret.zip -d dec
Archive:  secret.zip
[secret.zip] memo.txt password:
 extracting: dec/memo.txt

📌 Main options: results from this article

OptionTaskResult in this article
zip -rIncludes all subfolders and files inside the folderWithout -r, one line adding: site/; with -r, ten entries including .htaccess
zip -xLeaves out files that match a patternWith site/logs/* left out, only eight entries, without the logs folder and access.log
zip -uRe-adds only the files that changed after the zip file was madeOne line updating: site/index.html (deflated 90%); with nothing changed, no output and exit code 12
zip -dDeletes entries inside the zip filedeleting: site/logs/ and deleting: site/logs/access.log
zip -qHides the lines printed while compressingAll three commands compressed with -qr (-0, default, -9) finished without adding lines
zip -0Stores files without compressing themlevel0.zip at 37433 bytes, larger than the original file total
zip -9Compresses as small as possible (default -6)level9.zip 3874 bytes; level6.zip, made with the default, 4179 bytes
zip -eAsks for a password and encrypts the contentsAsks Enter password: and Verify password:, then adding: memo.txt (stored 0%)
unzip -lLists the stored entries without extractingsite.zip: 10 files, 35825 bytes in total
unzip -dSets the folder to extract into and creates it if it does not existStarts with creating: restore/site/, and the site folder structure is extracted under restore
unzip -oOverwrites all existing files without askingFive inflating lines with no prompt
unzip -nSkips existing files without askingNothing appears after the Archive: site.zip line
unzip -tTests the compressed data without extractingOK for each entry and No errors detected; the truncated broken.zip gives End-of-central-directory signature not found
unzip -OSets the character encoding of file names inside the zipWith -O CP949, the garbled names show up as 보고서.txt and 견적서.txt (Korean for "report" and "quote")
unzip -pSends the extracted contents to standard output instead of creating filesOnly the two lines of .htaccess appear, and no file is created

📎 Other options: per the official manual

OptionTask
zip -mDeletes the original files and folders after compressing (it deletes them after the zip file is complete, and the official manual recommends using it with -T)
zip -jStores only file names, without folder paths
zip -yStores a symbolic link as a link instead of the file it points to
zip -TTests the new zip file and leaves the original zip file unchanged if the test fails
zip -fReplaces only entries already in the zip file with changed files and adds no new files
zip -iIncludes only files that match the given pattern
zip -PPuts the password right on the command line (the official manual warns it is insecure)
unzip -jExtracts only the files into one folder without creating the folder structure inside the zip
unzip -xSets entries not to extract
unzip -qHides the lines printed while extracting
unzip -uExtracts only files missing from the disk and files that are newer
unzip -vAdds compression method, compressed size, ratio and CRC to the listing

3️⃣ How to use the unzip command

  • ↪️ Extracting zip on Linux with -d, -o and -n

To extract a zip file on Linux, write the zip file name after unzip. Without -d to set a folder, the files are extracted into the current folder (according to the official manual), so this time the restore folder was specified.

unzip site.zip -d restore
Archive:  site.zip
   creating: restore/site/
   creating: restore/site/css/
  inflating: restore/site/css/style.css
   creating: restore/site/js/
  inflating: restore/site/js/app.js
  inflating: restore/site/index.html
  inflating: restore/site/about.html
  inflating: restore/site/.htaccess

If the folder given with -d does not exist, unzip creates it, and the site folder structure is extracted beneath it as is.

Extracting again to the same place makes unzip stop at every file that already exists and ask whether to overwrite it. Choosing [N]one ends the extraction without overwriting any of the remaining files.

unzip site.zip -d restore
Archive:  site.zip
replace restore/site/css/style.css? [y]es, [n]o, [A]ll, [N]one, [r]ename: N

To handle this without prompts, add -o or -n. -o overwrites every existing file, and -n skips existing files. Because the official manual lists -o as a dangerous option, first make sure the folder is safe to overwrite before adding -o.

unzip -o site.zip -d restore
Archive:  site.zip
  inflating: restore/site/css/style.css
  inflating: restore/site/js/app.js
  inflating: restore/site/index.html
  inflating: restore/site/about.html
  inflating: restore/site/.htaccess
unzip -n site.zip -d restore
Archive:  site.zip

Extracting with -n where every file already exists prints nothing after the Archive line.

To extract only part of a zip file, put a path or pattern after the zip file name. Specifying [site/css/*] extracts only the css folder and style.css.

unzip site.zip 'site/css/*' -d part
Archive:  site.zip
   creating: part/site/css/
  inflating: part/site/css/style.css

4️⃣ unzip errors

  • ↪️ End-of-central-directory and garbled file names

Test a zip file received from another server with unzip -t before extracting it. If the compressed data has no problems, each entry shows OK, and the last line reads [No errors detected].

unzip -t site.zip
Archive:  site.zip
    testing: site/                    OK
    testing: site/css/                OK
    testing: site/css/style.css       OK
    testing: site/js/                 OK
    testing: site/js/app.js           OK
    testing: site/index.html          OK
    testing: site/about.html          OK
    testing: site/.htaccess           OK
No errors detected in compressed data of site.zip.

A zip whose end was cut off by an interrupted transfer ended with [End-of-central-directory signature not found]. This is the result of testing with -t a broken.zip that kept only the first 2,000 bytes of site.zip, which had become 2,436 bytes after the logs entries were deleted with -d.

unzip -t broken.zip
Archive:  broken.zip
  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
unzip:  cannot find zipfile directory in one of broken.zip or
        broken.zip.zip, and cannot find broken.zip.ZIP, period.

unzip reads the file list at the very end of a zip file (the central directory) first. That is why it could not test even the first entry of broken.zip, whose end was cut off.

Giving it a file that is not a zip produced the same message. Opening site.tar.gz, bundled with tar, in unzip ended with the same error, and a tar.gz file is extracted with the tar command instead.

unzip site.tar.gz
Archive:  site.tar.gz
  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
unzip:  cannot find zipfile directory in one of site.tar.gz or
        site.tar.gz.zip, and cannot find site.tar.gz.ZIP, period.

A zip file made on Windows sometimes stores its file names in a Windows character encoding rather than UTF-8. When report-win.zip, whose names were stored in CP949, was opened with unzip -l on a UTF-8 server, the file names came out as unreadable symbols.

unzip -l report-win.zip
Archive:  report-win.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
       26  10-28-2026 22:10   ║╕░э╝н.txt
       17  10-28-2026 22:10   ░▀└√╝н.txt
---------                     -------
       43                     2 files

If you write the character encoding of the Windows system that made the zip after -O, the names show up correctly, and files extracted with the same option are created with their original names.

unzip -O CP949 -l report-win.zip
Archive:  report-win.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
       26  10-28-2026 22:10   보고서.txt
       17  10-28-2026 22:10   견적서.txt
---------                     -------
       43                     2 files
unzip -O CP949 report-win.zip -d win
Archive:  report-win.zip
  inflating: win/보고서.txt
  inflating: win/견적서.txt

According to the unzip help, -O is the option for zip files made on DOS or Windows, and -I is for zip files made on other systems.

The error messages that came up while extracting, and what to check next, are listed below.

OutputMeaningWhat to check next
End-of-central-directory signature not foundThe file list at the end of the zip file was not found: the file is truncated or not a zipCompare the size with the original and download it again · use tar for tar.gz
cannot find or openNo file with that name in the current folderFile name and location with ls
skipping: … incorrect passwordThe password was wrong three times, so that file was skipped (exit code 82)Letter case of the password and the input language
File names garbled into symbolsNames stored in a Windows character encodingThat encoding (such as CP949) after -O

🔲 zip command simulator

In the simulator below, you can type the steps yourself: compress with zip, then list or extract with unzip.

zip command simulatorZip 3.0 · UnZip 6.00
[root@server work]#
It runs only in your browser and does not compress real files. Compression ratios are measured values, and files newly created in the simulator have estimated values. Use ↑↓ to recall commands you typed earlier.

🔢 FAQ & Recommended Content

Opening a .gz file compressed with gzip in unzip ended with [End-of-central-directory signature not found]. Decompressing it with [gzip -d readme.txt.gz] turned readme.txt.gz back into readme.txt. A .tar.gz, made by bundling several files with tar and then compressing with gzip, is extracted in one go with tar.

On the AlmaLinux 9 server we checked, zip and unzip were commands installed by the zip and unzip packages respectively. So on RHEL-based systems install them with [sudo dnf install zip unzip], and on Debian-based systems with [sudo apt install zip unzip] (based on the official Debian package list).

Put the zip file and the path inside it after unzip -p, and the contents go straight to the screen. Running [unzip -p site.zip site/.htaccess] printed only the two lines of .htaccess without creating a file.

ℹ️ Affiliate Disclosure
This site's content contains affiliate links. When a visitor buys a product or service through one of them, the site receives a commission from the seller. The amount the buyer pays(it goes down during event discounts ↓)does not go up. Posted prices, discounts, and stock reflect the time of writing and may differ, so confirm with the seller before buying. Products are chosen and reviewed by our own standards, and commissions do not affect the order or content of reviews.

Leave a Reply

Your email address will not be published. Required fields are marked *

Prove your humanity: 3   +   2   =