Compress an Executable in Place with bzexe
You will finish with an executable that keeps its original path but stores its machine code in a bzip2-compressed wrapper. Running that path will unpack a temporary copy and execute it. The original is kept beside it as PROGRAM~, so you have a recovery point while testing.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need the bzip2 package and write access to the directory containing the executable. The examples below use the installed bzip2 version 1.0.8-5.1ubuntu0.1. Compressing a system binary needs elevated privileges and can disrupt software that expects the file to be an ordinary binary, so test with a disposable copy first.
Checkpoint
This command changes files in place. Do not run it against a package-managed executable until you have a rollback plan and a reason to accept the operational risk.
1. Inspect the installed command
Confirm which script will run and read its short usage message. These are ordinary, read-only commands:
$ command -v bzexe
/usr/bin/bzexe
$ dpkg-query -W -f='${Package} ${Version}\n' bzip2
bzip2 1.0.8-5.1ubuntu0.1
$ bzexe
compress executables. original file foo is renamed to foo~
usage: bzexe [-d] files...
bzexe is a shell script supplied by bzip2. It does not create a file with a .bz2 suffix. Instead, it replaces the named executable and saves the previous file with a tilde suffix.
2. Prepare a harmless test executable
Use a copy in a temporary directory. The copy is still a real executable, but changing it cannot alter the installed true command:
$ work_dir="$(mktemp -d /tmp/bzexe-test.XXXXXXXXXX)"
$ cp /usr/bin/true "$work_dir/true"
$ chmod 755 "$work_dir/true"
$ ls -l "$work_dir/true"
-rwxr-xr-x ... true
Replace /usr/bin/true and the destination name only if you have a suitable test executable. Keep the path quoted. The script accepts one or more file names, but starting with one makes the backup and rollback easy to inspect.
Checkpoint
Run the copy before compression and check that it exits successfully:
$ "$work_dir/true"
$ printf 'status: %s\n' "$?"
status: 0
3. Compress the copy in place
Run bzexe with the file name. No sudo is needed for the temporary directory created above:
$ (cd "$work_dir" && bzexe ./true)
./true: 2.659:1, 3.008 bits/byte, 62.40% saved, 26936 in, 10129 out.
$ ls -l "$work_dir/true" "$work_dir/true~"
-rwxr-xr-x ... true
-rwxr-xr-x ... true~
The compression statistics depend on the input. The useful result is the pair of files: true is now a shell wrapper and true~ is the uncompressed original. The wrapper normally retains the original executable permissions. Check both files before deleting anything.
Warning
Do not remove true~ yet. It is the simplest undo path if the wrapper fails or the space saving is not worth the trade-off.
4. Run and verify the wrapper
Execute the compressed path as you would before:
$ "$work_dir/true"
$ printf 'status: %s\n' "$?"
status: 0
$ file "$work_dir/true"
/tmp/bzexe-test.XXXXXXXXXX/true: POSIX shell script, ASCII text executable
The wrapper finds bzip2, decompresses the payload into a temporary executable, runs it, then cleans up after a short delay. There is a small startup cost on every invocation. Programs that inspect their own name can also behave differently because the temporary unpacked program is used to do the work.
The wrapper depends on commands found through PATH, including tail, chmod, ln and sleep. A restricted service environment or an unexpected PATH can therefore break an otherwise valid wrapper. Test it in the same environment as the real caller.
5. Restore the original if needed
Restoration is a file replacement, so stop processes that might be using the executable first. Preserve the wrapper as a diagnostic copy, then move the backup into its original name:
$ mv "$work_dir/true" "$work_dir/true.bzexe-wrapper"
$ mv "$work_dir/true~" "$work_dir/true"
$ "$work_dir/true"
$ printf 'status: %s\n' "$?"
status: 0
This restores the original bytes and removes the tilde backup by moving it. If you need to keep both versions, copy the backup to a new name first and compare it with cmp. Do not overwrite a valuable file with a blind redirection.
6. Treat decompression as a version-specific check
The manpage documents -d for reversing the operation:
$ (cd "$work_dir" && bzexe -d ./true)
bzexe: ./true probably not in gzexe format, file unchanged.
On this installed bzip2 package, the command also reports a temporary-file creation error when tested against its own wrapper. That makes the documented decompression path unreliable here. Do not delete PROGRAM~ on the assumption that bzexe -d will be your recovery mechanism. Keep the backup, and use the explicit restore procedure in step 5 after checking the file and any running processes.
A non-file argument is rejected without changing the named files:
$ bzexe /path/to/does-not-exist
bzexe: /path/to/does-not-exist not a file
$ printf 'status: %s\n' "$?"
status: 1
A setuid or setgid executable is also left unchanged by the installed script. That is a safety boundary, not a failure to work around with permissions. Compression changes how the executable is launched and can create security concerns, so use an ordinary, non-privileged test file when learning the workflow.
Done means
- You checked the installed
bzexeand bzip2 version. - You tested a copy rather than changing a live or package-managed executable first.
- The wrapper ran with the target caller's real
PATHand returned the expected status. - The
PROGRAM~backup is still available, or you deliberately restored the original. - You have not relied on
bzexe -dwithout testing it on this package version.