tar Cheatsheet - tar Archive & Compression Reference
Bundling a directory before a backup, a code hand-off or a server migration always goes through tar, and the difficulty is choosing a compression format and avoiding parameters that cause irreversible damage. The sheet separates creating, listing, testing and extracting, then gives formats their own comparison: gzip as a balanced default, bzip2 smaller but slower, xz best ratio with threading at a time cost, and zstd as the pragmatic modern choice. Two behaviours matter for backups: tar records ownership by default, so extraction without --no-same-owner silently changes file owners, and --exclude decides what never enters the archive — node_modules, .git and caches belong there. The riskiest moment is extraction, where an archive containing ../ entries can write outside the target directory, so list with tar -tf before unpacking. Two performance notes: parallel compression with pigz for large trees, and --strip-components to avoid an extra nesting level on extraction.
Typical Use Case
For developers backing up directories, migrating servers and packaging releases. tar is not hard to remember commands for; it is hard on three counts: choosing a compression format (the speed versus ratio trade-off across gzip, zstd and xz), the trailing slash that decides whether you archive a directory or its contents, and the irreversibility of overwriting during extraction. This sheet covers packing, extraction, inspection, format comparison and advanced usage, with --exclude and --strip-components as the two parameters that save the most time and cause the most damage.
Pack & Compress 7
tar -cvf archive.tar dir/tar -czvf archive.tar.gz dir/tar -cjvf archive.tar.bz2 dir/tar -cJvf archive.tar.xz dir/tar --zstd -cvf archive.tar.zst dir/tar -czvf archive.tar.gz --exclude="*.log" dir/tar -czvf archive.tar.gz --exclude="node_modules" --exclude=".git" project/Extract 8
tar -xvf archive.tartar -xzvf archive.tar.gztar -xjvf archive.tar.bz2tar -xJvf archive.tar.xztar --zstd -xvf archive.tar.zsttar -xzvf archive.tar.gz -C /opt/tar -xzvf archive.tar.gz file.txttar -xzvf archive.tar.gz --strip-components=1List & Test 5
tar -tf archive.tar.gztar -tzvf archive.tar.gztar -tf archive.tar.gz | grep "config"gzip -t archive.tar.gztar -dvf archive.tarCompression Format Comparison 6
-z (gzip)-j (bzip2)-J (xz)--zstd (zstd)-a--use-compress-program=pigzOther Compression Tools 8
zip -r archive.zip dir/unzip archive.zip -d /opt/unzip -l archive.zipgzip file.txtgzip -k file.txtgunzip file.txt.gzzcat file.txt.gz7z x archive.7zAdvanced Usage 6
tar -rvf archive.tar newfile.txttar -uvf archive.tar dir/tar -czf - dir/ | ssh host "tar -xzf - -C /dest"tar -czf - dir/ | split -b 100M - archive.tar.gz.cat archive.tar.gz.* | tar -xzvf -tar -g snapshot.snar -czf backup.tar.gz dir/Common Examples 4
tar -czvf backup-$(date +%F).tar.gz /home/user/tar -czvf app.tar.gz --exclude="*.log" --exclude="tmp/" app/tar -xzvf package.tar.gz --strip-components=1 -C /opt/apptar -czf - /data | pigz > backup.tar.gzParameter matrix
| Parameter | Effect | Example |
|---|---|---|
-z (gzip) | 速度最快、兼容性最好 | tar -czvf a.tar.gz dir/ |
--zstd | 速度接近 gzip、压缩率更好,新系统推荐 | tar --zstd -cvf a.tar.zst dir/ |
-J (xz) | 压缩率最高但最慢 | tar -cJvf a.tar.xz dir/ |
-c / -x / -t | 创建 / 解压 / 列出不解压 | tar -tf a.tar.gz |
-v | 显示处理的文件名 | tar -czvf a.tar.gz dir/ |
--exclude | 打包时排除路径或模式 | --exclude="*.log" --exclude="node_modules/" |
--strip-components=N | 解压时去掉前 N 层目录 | tar -xzf a.tar.gz --strip-components=1 -C /opt |
-C dir | 切换到指定目录操作 | tar -xzf a.tar.gz -C /opt/app |
-k | gzip 压缩时保留原文件 | gzip -k file.txt |
pigz | 多线程压缩大目录 | tar -czf - /data | pigz > b.tar.gz |
split -b 100M | 分卷便于传输 | tar -czf - dir/ | split -b 100M - a.tar.gz. |
gzip -t | 测试压缩包完整性,无输出即正常 | gzip -t a.tar.gz |
Common pitfalls
Symptom解压后目录多了一层,出现 /opt/app/app/ 这样的结构。
Cause打包时源目录写法或解压时未剥离顶层目录。
Fix用 --strip-components=1 解压,或打包时用 -C dir . 让内容不带顶层目录。
Symptom打包体积巨大,node_modules 与 .git 都在里面。
Cause未使用 --exclude。
Fixtar -czvf a.tar.gz --exclude="node_modules/" --exclude=".git" --exclude="*.log" app/
Symptom解压到指定目录失败,提示权限或路径不存在。
Cause目标目录未创建。
Fix先 mkdir -p /opt/app 再配合 -C 指定。
Symptom对 .tar.gz 使用 tar -r 追加文件报错。
Cause追加只支持未压缩的 .tar 归档。
Fix需要追加内容时重新打包,或先用 gzip -d 解压再追加最后重压。
Symptom解压时报路径穿越相关警告或文件落到意外位置。
Cause归档内含 ../ 或绝对路径条目。
Fix先用 tar -tf 查看条目清单,对来路不明的包先解到隔离目录。
Symptomsplit 分卷后合并解压报损坏。
Cause漏合并某个分卷,或合并顺序不对。
Fix确认所有 .part 文件齐全后 cat a.tar.gz.* | tar -xzf - 合并解压。
Troubleshooting
1先列内容确认结构再决定怎么解
tar -tzvf a.tar.gz | head -20查看条目、大小与权限;对来路不明的包尤其要先看这一步。
2解压到指定目录并剥掉顶层
mkdir -p /opt/app && tar -xzf a.tar.gz --strip-components=1 -C /opt/app发布包部署的标准写法,避免双层嵌套。
3校验压缩包是否完整
gzip -t a.tar.gz && echo OK无输出即正常;配合 && echo 给出明确结论便于脚本判断。
4排除无关目录后再打包
tar -czvf app.tar.gz --exclude="*.log" --exclude="node_modules/" --exclude=".git" app/体积通常能降一个数量级,也避免把密钥打进包里。
5大目录用 pigz 多线程加速
tar -czf - /data | pigz > backup.tar.gz多核并行压缩,通常比单线程 gzip 快数倍。
Command Examples
Package a project while excluding logs and dependencies
tar -czvf app.tar.gz --exclude="*.log" --exclude="node_modules/" --exclude=".git" app/--exclude 在打包时过滤,比先打包再删更省时间和磁盘。多阶段构建的项目务必排除 node_modules,它通常是体积大头且可由 npm ci 重建。
Output
app/package.json app/src/ app/src/main.ts app/dist/ app/dist/index.js
Extract into a target directory, stripping the top folder
tar -xzvf package.tar.gz --strip-components=1 -C /opt/app--strip-components=1 去掉包里的第一层目录,-C 指定落点。发布包部署时最常用,否则会得到 /opt/app/package/ 这样的双层结构。
Output
package.json src/ src/main.ts dist/index.js
Inspect an archive before extracting
tar -tzvf package.tar.gz | head -20-t 只列表不解压,-v 显示权限与时间。确认路径结构与权限位符合预期后再解,尤其对来路不明的压缩包。
Output
-rw-r--r-- root/root 1024 2026-09-28 10:11 package.json drwxr-xr-x root/root 4096 2026-09-28 10:11 src/ -rwxr-xr-x root/root 24576 2026-09-28 10:12 dist/index.js
Package while preserving timestamps
tar -czvf backup-$(date +%F).tar.gz /home/user/
gzip -t backup-$(date +%F).tar.gz && echo OKgzip -t 测完整性,无输出即正常;这里用 && echo OK 把它变成一条明确的结论。用日期命名避免多次备份互相覆盖。
Output
OK
Common Pitfalls
- tar -x overwrites same-named files without prompting, and paths containing .. or absolute paths can write outside the target — inspect with -t before extracting anything untrusted.
- Without --exclude, tar -c bundles node_modules and .git too, which can multiply the size and leak secrets.
- The flag after -f must match the compression actually used; mismatching -j with a .gz file silently produces the wrong format.
- Appending with tar -r only works on uncompressed .tar — using it on .tar.gz errors out or corrupts the archive.
- After split, every volume must be concatenated with cat archive.* before extracting, or you get a truncated archive.
Tips
- Mnemonic: c=create, x=extract, t=list, z=gzip, j=bzip2, J=xz.
- Before extracting, run tar -tf to inspect contents and confirm there's no ../ path traversal (zip-slip risk).
- For large files, zstd --long=31 uses long-distance matching — 5-10x faster than gzip with better ratio.
- Appending works only on uncompressed .tar; for .tar.gz you must decompress and repackage.
- pigz is the multi-threaded gzip; for large files use tar -cf - dir | pigz > out.tar.gz to speed up greatly.
- Put -C (target dir) after the filename; --strip-components drops the first N directory levels to avoid nested extraction.
FAQ
Which compression format should I use — gzip, bzip2, xz or zstd?
It comes down to speed versus ratio. gzip is fastest with the widest compatibility and is fine for everyday archiving; zstd is close to gzip in speed with a noticeably better ratio and is the better default on modern systems; xz compresses hardest but is slowest, which suits files you archive and rarely reopen; bzip2 is largely obsolete now. The flags are -z, --zstd and -J respectively.
How do I exclude node_modules and logs when creating a tarball?
Use --exclude, for example tar -czvf app.tar.gz --exclude="*.log" --exclude="node_modules/" --exclude="tmp/" app/. Better still, think of it like .gitignore or .dockerignore — clean up before packing, since these files dominate the size and can always be regenerated. Also prefer -C to change directory so the archive does not gain an extra nesting level.
How do I extract without the top-level directory?
Add --strip-components=1: tar -xzvf package.tar.gz --strip-components=1 -C /opt/app. The archive entry app/package.json then lands at /opt/app/package.json instead of /opt/app/app/package.json. This is the standard trick for release tarballs and deploy scripts, usually paired with -C to pick the destination.
How can I inspect an archive without extracting it?
Use -t to list rather than extract: tar -tzvf archive.tar.gz prints names, sizes and permissions without unpacking. Pipe it to search: tar -tf archive.tar.gz | grep "config". And gzip -t archive.tar.gz quickly tests integrity — no output means the archive is fine.
Packing a large directory is slow — how do I speed it up?
Compression is the bottleneck, so use pigz for multi-threaded compression: tar -czf - /data | pigz > backup.tar.gz. It parallelizes across cores and is typically several times faster than single-threaded gzip. If a single file is too big, split it with tar -czf - dir/ | split -b 100M - archive.tar.gz. and reassemble later with cat archive.tar.gz.* | tar -xzvf -.
Official References
Each command links to its official documentation below, so you can verify the latest usage and read deeper.
Maintained by LaoHand
Publicly updated on Jul 21, 2026, continuously proofread against official docs.
Contact Us
Wrong command or description? Send us corrections, business inquiries or product feedback by email.
Contact Us