pax - the POSIX archiver
The POSIX archiver, pax(1)
, is an attempt at a standardized archiver with
the best features of tar and cpio, able to handle all common archive
types.
Overview
There are four basic operation modes to list, read, write and copy
archives. They're switched with combinations of -r
and -w
command
line options:
Mode | RW-Options |
---|---|
List | none |
Read | -r |
Write | -w |
Copy | -rw |
The option to specify the pathname of a file is
-f
. Without-f
,pax(1)
will attempt to read from standard input and write to standard output.
List
pax(1)
writes the list of archive members to standard output (a table of
contents). If a pattern match is specified on the command line, only
matching filenames are printed.
Read
pax(1)
will read archive data and extract the members to the current
directory. If a pattern match is specified on the command line, only
matching filenames are extracted.
When reading an archive, the archive type is determined from the archive data.
Write
pax(1)
creates a new archive or append to an existing one. All files and
directories specified on the command line are inserted into the archive.
The archive is written to standard output by default.
If no files are specified on the command line, filenames are read from STDIN.
The write mode is the only mode where you need to specify the archive
type with -x <TYPE>
, e.g. -x ustar
. See pax(1)
manpage for supported
archive formats.
pax(1)
in OpenBSD creates archives in ustar format by default
Copy
pax(1)
can be used to copy directory hierarchies.
Usage
Berkeley
pax(1)
supports options-z
and-j
to filter archive files throughgzip(1)
orbzip2(1)
.
Creating an archive
archive contents to stdout:
pax -w >archive.tar foo.txt bar.txt *.jpg foobar/
equivalent, write archive contents directly to a file
pax -w -f archive.tar foo.txt bar.txt *.jpg foobar/
in the above example pax(1)
is in write mode, the given filenames are
packed into an archive:
foo.txt
andbar.txt
are normal files. They will be packed.*.jpg
is a pathname glob for the shell. The shell will substitute all matching filenames beforepax(1)
is executed. The result is a list of filenames that will be packed.foobar/
is a directory. Everything in this directory will be packed into the archive.
pax(1)
will write the pathnames of the files inserted into the archive to STDERR when-v
option exists.
If no filename arguments are specified, pax(1)
attempts to read filenames
from STDIN, separated by newlines. This way we can easily combine
find(1)
with pax(1)
:
find . -name '*.txt' | pax -wvf textfiles.tar
The -s
option modifies the archive member names according to the
substitution expression. We use it to exclude a file.
pax -wf archive.tar -s',.*/tmp/.*,,' /home
Multiple -s options can be specified.
pax -wf archive.tar -s',.*/tmp/.*,,' -'s/.*~//' /home
Listing archive contents
pax <archive.tar
equivalent, with option -f
pax -f archive.tar
pax(1)
lists archive members in als -l
-like format, when you give the-v
option:
pax -v <archive.tar
orpax -vf archive.tar
Extracting from an archive
Extract all files:
pax -rf archive.tar
extract files matching specific patterns:
pax -rf archive.tar '*.txt'
extract files not matching specific patterns (with inverted pattern):
pax -rf archive.tar -c '*.txt'
Copying files
To copy directory contents to another directory,
similar to a GNU's cp -a
command, use:
mkdir destdir
pax -rw dir destdir
Examples
Backup config files changed less than 3 days ago:
find /etc -type f -mtime -3 | pax -wf /var/backups/etc.tar
Copy only the directories, not the files:
mkdir /target
find . -type d -print | pax -rw -d /target
The
-d
option tellspax(1)
not to recurse into directories it reads.
Backup anything that changed since the last backup:
find . -newer /var/backups/mylastbackup -print0 \
| pax -0 -w -d -f /var/backups/mybackup.tar
touch /var/run/mylastbackup
Copy one directory to another machine.
One approach would be to create a tarball, copy to the target, log in to the target and unpack the tarball.
But there's a much easier way: Invoke pax on both machines, and connect the output of one to the input of the other:
$ pax -w dir1/ | ssh remotehost 'cd /tmp/ && pax -r'
pax -w
writes to standard output.ssh
reads standard input and attaches it to whatever utility is invoked, which of course in this case is pax again.pax -r
reads from standard input and creates the files from that archive.
Mastering pax
To learn about all the power of pax(1)
see the fantastic manpage.
From tar to pax
an alias can be useful :-D
alias tar='echo USE PAX, idiot. pax(1) is the standard archiver!; # '
Here is a quick table comparing (GNU) tar and pax to help you to make the switch:
TAR | PAX | Notes |
---|---|---|
tar xzvf file.tar.gz | pax -rvz -f file.tar.gz | POSIX: gunzip <file.tar.gz | pax -rv |
tar czvf archive.tar.gz ... | pax -wvz -f archive.tar.gz ... | POSIX: pax -wv path | gzip > archive.tar.gz |
tar xjvf file.tar.bz2 | bunzip2 <file.tar.bz2 | pax -rv | |
tar cjvf archive.tar.bz2 ... | pax -wv ... | bzip2 > archive.tar.bz2 | |
tar tzvf file.tar.gz | pax -vz -f file.tar.gz | POSIX: gunzip <file.tar.gz | pax -v |