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 through gzip(1) or bzip2(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:

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 a ls -l-like format, when you give the -v option:

pax -v <archive.tar or pax -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 tells pax(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'

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