zip Command in Linux: Zip Files and Directories

When you need to share logs, configs, project files, or a whole directory with users on Linux, macOS, or Windows, ZIP is often the most practical archive format to choose. The zip command creates .zip archives from files and directories directly from the terminal.
A ZIP file is a data container that can hold one or more compressed files or directories. Compressed files take up less disk space and are easier to transfer between systems. This guide explains how to create ZIP archives in Linux using the zip command.
The zip command takes the name of the archive first, followed by the files and directories you want to add:
zip [OPTIONS] archive.zip file1 file2 ...Quick Reference
For a printable quick reference, see the ZIP/UNZIP cheatsheet .
| Task | Command |
|---|---|
| Zip files | zip archive.zip file1 file2 |
| Zip a directory recursively | zip -r archive.zip directory/ |
| Zip non-hidden files in the current directory | zip archive.zip * |
| Zip current directory, including hidden files | zip -r ../archive.zip . |
| Add or update files in an archive | zip archive.zip newfile |
| Remove a file from an archive | zip -d archive.zip file1 |
| Store files without directory paths | zip -j archive.zip dir/file1 |
| Store symbolic links instead of their targets | zip -y -r archive.zip directory/ |
| Zip without compression | zip -0 archive.zip file1 file2 |
| Maximum compression | zip -9 -r archive.zip directory/ |
| Use bzip2 compression | zip -r -Z bzip2 archive.zip directory/ |
| Exclude files | zip -r archive.zip directory/ -x "*.log" |
| Password-protected archive | zip -e archive.zip file1 file2 |
| Split archive into 1GB parts | zip -s 1g -r archive.zip directory/ |
| Quiet mode (no output) | zip -q archive.zip file1 file2 |
Installing zip
zip
is a command-line utility that helps you create Zip archives. Ubuntu Desktop includes it, but server and minimal installations often do not. You can install it using your distribution’s package manager.
Install zip on Ubuntu, Debian, and Derivatives
sudo apt install zipInstall zip on Fedora, RHEL, and Derivatives
sudo dnf install zipInstall zip on Arch Linux
sudo pacman -S zipZipping Files
To zip one or more files, specify the files you want to add to the archive separated by space:
zip archivename.zip filename1 filename2 filename3 adding: filename1 (deflated 63%)
adding: filename2 (stored 0%)
adding: filename3 (deflated 38%)By default, the zip command prints the names of the files added to the archive and the compression method.
If the archive name has no extension, zip adds .zip automatically. For example, zip archivename filename creates archivename.zip. A name with a different extension, such as backup.bak, is used as is.
To suppress the output of the zip command, use the -q option:
zip -q archivename.zip filename1 filename2 filename3Zipping Directories
To zip a directory including the contents of its subdirectories, use the -r (recursive) option:
zip -r archivename.zip directory_nameYou can also add multiple files and directories in the same archive:
zip -r archivename.zip directory_name1 directory_name2 file1 file2When the directory contains symbolic links, zip follows them by default and stores a copy of the file each link points to. If you want the archive to keep the links themselves, add the -y option:
zip -y -r archivename.zip directory_nameZipping the Current Directory
To zip everything in the current directory, including hidden files and directories, run zip from inside the directory and write the archive outside it:
zip -r ../archivename.zip .The dot (.) tells zip to include the current directory contents. The zip utility skips the archive it is writing, so the archive does not end up inside itself, but writing it to the parent directory keeps the archive out of the directory tree you are packing and out of the way if you run the command again.
Adding Files to an Existing Archive
You do not have to rebuild an archive from scratch to change what it holds. Running zip against an archive that already exists adds the new files and refreshes the ones that changed:
zip archivename.zip newfile subdir/anotherfile adding: newfile (deflated 41%)
updating: subdir/anotherfile (stored 0%)The output tells you what happened to each entry. Files that were not in the archive show up as adding, while files that were already there show up as updating.
If you only want to refresh entries that are already in the archive, use the -f (freshen) option. It compares the timestamps and rewrites an entry only when the file on disk is newer, so nothing new is added:
zip -f archivename.zip subdir/anotherfileRemoving Files from an Archive
To delete entries from an archive, use the -d option followed by the paths as they appear inside the archive:
zip -d archivename.zip subdir/anotherfiledeleting: subdir/anotherfileThe paths must match the ones stored in the archive, not the paths on disk. If you are not sure how an entry is named, list the archive contents first with unzip -l archivename.zip.
Excluding Files from a Zip Archive
To skip files or directories, use the -x option followed by one or more patterns:
zip -r archivename.zip directory_name -x "*.log" "*.tmp"The command above creates an archive from directory_name but excludes files ending in .log and .tmp.
You can also exclude a directory by matching its path:
zip -r archivename.zip directory_name -x "directory_name/cache/*"Compression Methods and Levels
The default compression method of Zip is deflate. If the zip utility determines that a file cannot be compressed, it simply stores the file in the archive without compressing it using the store method. In most Linux distributions, the zip utility also supports the bzip2 compression method.
To specify a compression method, use the -Z option:
zip -r -Z bzip2 archivename.zip directory_name...
adding: sub_dir/ (stored 0%)
adding: sub_dir/file1 (bzipped 52%)
adding: sub_dir/file2 (bzipped 79%)The zip command allows you to specify a compression level using a number prefixed with a dash from 0 to 9. The default compression level is -6. When using -0, all files will be stored without compression. -9 will force the zip command to use optimal compression for all files.
For example, to use the compression level -9, you would type:
zip -9 -r archivename.zip directory_nameThe higher the compression level, the more CPU-intensive the zip process is, and it will take more time to complete.
Creating a Password-Protected Zip File
To create an encrypted archive, use the -e option. When you encrypt a directory, combine it with -r:
zip -er archivename.zip directory_nameDo not leave out -r here. Without it, zip stores only the empty directory entry and none of the files inside it.
You will be prompted to enter and verify the archive password:
Enter password:
Verify password:The -e option uses traditional ZIP encryption. It is useful for simple sharing, but it is not the right choice for highly sensitive data. For stronger encryption, use a dedicated tool such as gpg or age.
Creating a Split Zip File
Imagine you want to store the Zip archive on a file hosting service that has a file size upload limit of 1GB, and your Zip archive is 5GB.
You can create a new split Zip file using the -s option followed by a specified size. The multiplier can be k (kilobytes), m (megabytes), g (gigabytes), or t (terabytes):
zip -s 1g -r archivename.zip directory_nameThe command above will keep creating new archives in a set after it reaches the specified size limit. To see the parts, list the files that share the archive name:
ls archivename.*archivename.z01
archivename.z02
archivename.z03
archivename.z04
archivename.zipThe numbered files hold the first parts of the archive, and archivename.zip is the last part of the set, not a complete archive. To extract the set, join the parts into a single file first:
zip -s 0 archivename.zip --out joined.zipYou can then extract joined.zip with unzip. Running unzip on the split set itself fails with a multi-part archive warning
.
Ownership and Permissions
When you create an archive on Linux, zip stores the permission bits of each file along with its owner and group IDs. The unzip command restores the permissions by default, so an executable script stays executable after extraction.
Ownership is handled differently. By default, the extracted files are owned
by the user that runs unzip. The -X option restores the stored owner and group, but changing a file to another user requires root, so in practice you run sudo unzip -X. The owner and group are stored as numeric IDs, so on another system they map to whichever accounts use those IDs there. The setuid, setgid, and sticky bits are also dropped unless you pass the -K option.
Archives created on Windows do not carry Linux permissions at all, and zip stores hard links as separate copies of the file. For full backups that need to keep ownership and hard links intact, use the tar
command instead.
Common Options
The zip command accepts several options:
-r- Recurse into directories.-q- Quiet mode, suppress output.-e- Encrypt the archive with a password.-s size- Create a split archive with the specified segment size.-Z method- Set the compression method (deflate,store,bzip2).-0to-9- Set the compression level (0 = store only, 9 = maximum compression).-x pattern- Exclude files matching the pattern.-j- Store just the file names, without directory paths.-u- Update existing entries if the file on disk is newer and add new files.-f- Update existing entries if the file on disk is newer without adding new files.-d- Delete entries from an existing archive.-y- Store symbolic links as links instead of copying the files they point to.-T- Test the integrity of the archive after writing it.
Troubleshooting
zip: command not found
Install the zip package using your distribution package manager.
Permission denied
You do not have write permission in the target directory. Run the command in a directory you own or use sudo when appropriate.
The archive contains only an empty directory
You zipped a directory without the -r option. The output shows a single line such as adding: directory_name/ (stored 0%), and none of the files inside are added. Run the command again with -r.
zip warning: name not matched
One of the paths you passed does not exist. Check the spelling and your current working directory. When none of the paths match, zip stops with zip error: Nothing to do! and does not create the archive.
FAQ
How do I zip a directory in Linux?
Use zip -r archive.zip directory_name. The -r option tells zip to recurse into the directory and include all files and subdirectories.
How do I unzip a file in Linux?
Use the unzip
command: unzip archive.zip. To extract to a specific directory, use unzip archive.zip -d /path/to/directory.
How do I add a file to an existing zip archive?
Run zip archive.zip newfile. The zip command adds files that are not in the archive yet and updates the ones that changed, so you do not need to create the archive again.
How do I list the contents of a zip file?
Use unzip -l archive.zip. The output shows the size, timestamp, and stored path of every entry, which is also the fastest way to check how a path is named before deleting it with zip -d.
Does zip preserve file permissions?
Yes. The zip command stores the permission bits, and unzip restores them when you extract the archive. To restore the original owner and group as well, extract the archive with sudo unzip -X. For full backups, tar is the safer choice.
How do I exclude files from a zip archive?
Use the -x option followed by the pattern. For example, to exclude all .log files: zip -r archive.zip directory/ -x "*.log".
What is the difference between zip and gzip?zip creates an archive that can contain multiple files and directories. gzip compresses a single file and is typically used together with tar (as .tar.gz) to archive multiple files.
Conclusion
Use zip archive.zip file1 file2 for a few files and zip -r archive.zip directory/ when you need to include a directory tree. Extract ZIP archives with unzip
; for full backups that need to preserve ownership and hard links, use tar
.
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 1000+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page