bzip2 compresses a file into .bz2, checks its integrity without unpacking it, and reads compressed text without a temporary file. Damaged stream? bzip2recover salvages what it can. Allow about fifteen minutes. You need the bzip2 package and a writable working directory; none of these examples needs elevated privileges.
The installed program is bzip2 1.0.8, released on 13 July 2019. The four names in this guide are one program with different invocation names: bzip2 compresses by default, bunzip2 decompresses, bzcat writes decompressed data to standard output, and bzip2recover splits a damaged stream into candidate blocks.
Start with the version and path. This confirms which implementation your shell will run:
$ command -v bzip2
/home/linuxbrew/.linuxbrew/bin/bzip2
$ bzip2 --version
bzip2, a block-sorting file compressor. Version 1.0.8, 13-Jul-2019.
Your path can differ. The manual page describes the 1.0.8 command used here, so do not assume options from another compressor are interchangeable: bzip2's command-line options resemble GNU gzip's, but are not identical.
Checkpoint: If bzip2 --version does not run, install the package through your normal system package manager before continuing. Do not use sudo merely to compress a file you own.
Make a copy of a real input before practising, or replace the placeholder with a file you intend to compress:
$ cp /path/to/report.txt /tmp/report-for-bzip2.txt
$ bzip2 /tmp/report-for-bzip2.txt
$ ls -l /tmp/report-for-bzip2.txt.bz2
-rw-r--r-- 1 user user 1234 Sep 22 12:00 /tmp/report-for-bzip2.txt.bz2
Compression replaces the input with report-for-bzip2.txt.bz2; the original path is no longer present. The command normally preserves the input's modification date and permissions on the compressed output, where the filesystem supports that.
/tmp/report-for-bzip2.txt.bz2 already exists, bzip2 refuses to overwrite it.-f or --force as destructive. It permits overwriting and can also break a hard link to the input. Check the destination first rather than adding -f reflexively.Use -t for an integrity check. It performs a trial decompression and throws the result away, so it does not recreate the original file:
$ bzip2 -t /tmp/report-for-bzip2.txt.bz2
$ printf 'exit status: %s\n' "$?"
exit status: 0
A status of zero means the compressed data passed bzip2's CRC checks. It does not recover a damaged file, and it does not prove the contents are what you wanted: check the path and, where appropriate, compare a digest with a trusted value.
The documented exit statuses are useful in scripts:
Capture $? immediately, before running another command.
bunzip2 restores the name by removing .bz2, .bz, .tbz2 or .tbz, and normally removes the compressed input after successful decompression:
$ bunzip2 /tmp/report-for-bzip2.txt.bz2
$ test -f /tmp/report-for-bzip2.txt && echo 'restored'
restored
Use -k or --keep when you need both files:
$ bzip2 /tmp/report-for-bzip2.txt
$ bunzip2 --keep /tmp/report-for-bzip2.txt.bz2
$ test -f /tmp/report-for-bzip2.txt.bz2 && echo 'archive kept'
archive kept
If the output file already exists, decompression also refuses to overwrite it unless you use -f, an option that can destroy an existing destination: stop and compare the files first. To undo the ordinary decompression example, recompress the restored file with bzip2; to undo a test-only operation, there is nothing to undo.
Use bzcat when the result should go to standard output instead of a guessed filename. Handy for a pipeline or a quick inspection:
$ bzcat /path/to/report.txt.bz2 | sed -n '1,20p'
first line of the report
another line of the report
Do not redirect into the original path unless you have deliberately planned the replacement. A safer conversion writes a new destination:
$ bzcat /path/to/report.txt.bz2 > /tmp/report-unpacked.txt
$ cmp -- /tmp/report-unpacked.txt /path/to/report.txt
$ echo $?
0
The output of several files is concatenated in argument order. Similarly, bzip2 -c writes compressed data to standard output and bzip2 -dc decompresses to it. Without filenames, bzip2 reads standard input and writes standard output, but it refuses to write compressed binary data directly to a terminal.
Compression uses a block size of 100,000 to 900,000 bytes with -1 through -9; the default is -9. Larger blocks can improve compression but need more memory. The setting is recorded in the archive, so decompression reads the needed block size straight from the header: consequently, -1 through -9 do nothing useful when decompressing.
On a low-memory machine, -s reduces memory use for compression, decompression and testing. During compression it selects a 200 kB block size; during decompression it uses a slower algorithm needing about 2.5 bytes per block byte. Use it as a resource choice, not as a corruption repair option.
$ bzip2 -s /path/to/large-input.log
$ bzip2 -t /path/to/large-input.log.bz2
Keep the output name in mind: the first command removes large-input.log. Add -k if retaining the input matters.
Warning: Recovery is best-effort and can produce incomplete data. Work on a copy, and write recovered files into a separate directory so the damaged source remains available:
$ mkdir /tmp/bzip2-recovery
$ cp /path/to/damaged-file.bz2 /tmp/bzip2-recovery/input.bz2
$ cd /tmp/bzip2-recovery
$ bzip2recover input.bz2
rec00001input.bz2
rec00002input.bz2
The exact number of files depends on the blocks found. The names are numbered so a wildcard processes them in order. Test each candidate before extracting it:
$ for block in rec*input.bz2; do
> if bzip2 -t -- "$block"; then
> printf 'usable: %s\n' "$block"
> else
> printf 'damaged: %s\n' "$block" >&2
> fi
> done
$ bzip2 -dc -- rec*input.bz2 > recovered-data
Only the blocks that pass the CRC test are trustworthy. The final command concatenates their uncompressed data in filename order; it does not recreate missing material or repair a damaged block. A damaged file containing only one compressed block is unlikely to yield useful recovery.
Checkpoint: Compare recovered-data with any independent copy. If the data is irreplaceable, stop here and preserve the original, the recovery directory and the command output for a specialist rather than repeatedly modifying the evidence.
bzip2 -t returned status 0 before you relied on the archive.bunzip2 -k when retaining the compressed input mattered.bzcat or bzip2 -dc for a controlled standard-output pipeline.