Module 8 · Archives, compression and the network
tar: creating archives
Bundle a whole directory tree into one file with tar: create, see what goes in, leave things out, and control the paths stored inside.
What you will learn
- Create a tar archive from files and directories with `tar cf`.
- Use `-v`, `-C` and `--exclude` to control what goes in and how it is named.
- Know that tar bundles but does not compress.
Copying a project, sending a set of logs or taking a backup all have the same problem: many files, many directories, permissions and dates that should survive the trip. tar (from *tape archive*, because it was born to write to tape drives) solves it by gluing a whole tree into one file, the archive or *tarball*. Inside, every file keeps its name, its path, its owner, its permissions and its modification time.
The three letters: c, f, v
tar always needs one operation: c to create, t to list, x to extract (the next lesson covers the last two). Then almost always f NAME, the archive file to write; without it tar would try the old tape device. v (verbose) prints each name as it is added. The letters can be written in a bundle without a dash, the traditional way, or with one: tar cvf and tar -cvf are the same. The f must come last in the bundle because the next word is its file name.
~% cd lab/l71
~% tar cvf docs.tar docs
docs/
docs/notes.txt
docs/report.txt
~% ls -l docs.tar
-rw-r--r-- 1 root root 3584 Oct 4 23:16 docs.tar
~% tar cf both.tar docs logs # several sources in one archive
Directories are added recursively: name docs and everything under it goes in. Notice the size: two tiny text files became 3584 bytes. tar stores each file in 512-byte blocks plus a header block per entry, and pads the end. That is the key fact of this lesson: tar bundles, it does not compress. Compression is a separate step you will meet in lesson 73.
Paths inside the archive: -C
tar stores each name exactly as you typed it. Archive docs from inside lab/l71 and the members are docs/.... Archive /root/lab/l71/docs and they become root/lab/l71/docs/...: tar drops the leading / (it says so with *removing leading '/' from member names*) so that extracting can never overwrite system files, but the long path stays. Whoever unpacks it gets a root/lab/l71 tree they did not want. The fix is -C DIR, which makes tar change into DIR before reading the names that follow, without you having to cd:
~% tar cf /root/lab/l71/abs.tar /root/lab/l71/docs
tar: removing leading '/' from member names
~% tar tf /root/lab/l71/abs.tar | head -1
root/lab/l71/docs/
~% tar cf /root/lab/l71/clean.tar -C /root/lab/l71 docs
~% tar tf /root/lab/l71/clean.tar | head -1
docs/
Leaving things out
--exclude PATTERN skips every name that matches a shell-style pattern, and can be repeated. Quote the pattern so the shell does not expand it first. For long lists, put one pattern per line in a file and pass it with -X FILE; the opposite, -T FILE, archives only the names listed in a file.
~% tar cvf backup.tar --exclude '*.log' docs logs
docs/
docs/notes.txt
docs/report.txt
logs/
logs/README
| Letter | Meaning |
|---|---|
c | Create a new archive |
f FILE | The archive file (- means stdout) |
v | List each name while working |
-C DIR | Change into DIR first |
--exclude PAT | Skip names matching PAT |
Commands in this lesson
| Command | What it does |
|---|---|
tar cf out.tar dir | Create out.tar from dir, recursively. |
tar cvf out.tar a b | Same, several sources, printing each name. |
tar cf out.tar -C /path dir | Change into /path first, so names start at dir/. |
tar cf out.tar --exclude '*.log' dir | Leave out names matching a pattern. |
tar cf out.tar -T list.txt | Archive only the names listed in a file. |
Quiz
What does `tar cf site.tar site` do?
- Compresses site into a smaller file
- Bundles the site directory, recursively, into site.tar
- Extracts site.tar into site
- Copies site.tar over site
Why must `f` be the last letter in a bundle like `cvf`?
- Alphabetical order is required
- The word right after it is taken as the archive file name
- f means 'finish'
- It is not required at all
You run `tar cf b.tar /root/lab/docs`. What do the member names look like?
- /root/lab/docs/...
- root/lab/docs/... (leading slash removed)
- docs/...
- Just the file names, no directories
Which command leaves every .log file out of the archive?
- tar cf a.tar --exclude '*.log' logs
- tar cf a.tar logs -v '*.log'
- tar xf a.tar '*.log'
- tar cf a.tar logs | grep -v log
tar was told to archive a file that does not exist. What happens?
- Nothing is written and no message appears
- It archives the rest, reports the error and exits with a non-zero status
- It creates an empty placeholder file
- It deletes the archive
Practice
Create the archive `/root/lab/l71/docs.tar` containing the directory `/root/lab/l71/docs` and everything in it.
Create `/root/lab/l71/backup.tar` with both `docs` and `logs` from `/root/lab/l71`, but without any `.log` file. `logs/README` must still be inside.
Without `cd`, create `/root/lab/l71/clean.tar` holding the `docs` directory so that its member names start with `docs/` (not `root/lab/...`).
Open this lesson in the app to do the tasks in a real Linux machine and have them checked.