In Debian and Ubuntu system administration, administrators occasionally need to modify or replace a binary, helper utility, or script provided directly by an upstream APT package. If you edit or overwrite a package-managed file directly in /usr/bin/ or /etc/, the next system update (apt upgrade) will silently overwrite your customizations or trigger interactive package maintainer conflict prompts. To permanently override, rename, and relocate package-managed files without breaking package manager integrity, Debian and Ubuntu provide the low-level utility dpkg-divert.
Understanding How dpkg-divert Operates
The dpkg-divert tool manipulates the central dpkg database (specifically /var/lib/dpkg/diversions). When a diversion is active on a path:
- Automatic File Redirection: Whenever
dpkgoraptunpacks an update containing the diverted file, it automatically writes the file to the diversion path (e.g.,/usr/bin/tool.distrib) instead of the original location. - Safe Custom Injections: Your custom replacement binary or wrapper script remains undisturbed at the original target location (e.g.,
/usr/bin/tool). - Conflict Prevention: The package manager remains completely aware of the change and never flags the file as corrupted or modified during checksum verifications.
Listing Active File Diversions
Before creating a diversion, inspect existing diversions already configured by the operating system or third-party packages:
dpkg-divert --list
The output reports diverted files across the filesystem:
diversion of /usr/share/man/man1/sh.1.gz to /usr/share/man/man1/sh.distrib.1.gz by dash
diversion of /bin/sh to /bin/sh.distrib by dash
To check if a specific binary or configuration file is currently diverted:
dpkg-divert --list '/usr/bin/python3'
Creating a Safe File Diversion
Suppose you need to replace a system binary or daemon script (for example, /usr/bin/update-motd) with a custom script that injects enterprise monitoring alerts:
To instruct dpkg to divert the file and physically rename the existing file in one atomic step:
sudo dpkg-divert --divert /usr/bin/update-motd.distrib --rename /usr/bin/update-motd
The switches operate as follows:
--divert <new-path>: The destination path where official package updates will be placed.--rename: Physically renames the existing file on the filesystem to the diverted name immediately. Without--rename, you must move the existing file manually.
Verify that the file has been moved:
ls -l /usr/bin/update-motd*
You will observe /usr/bin/update-motd.distrib, while the original path /usr/bin/update-motd is now clear for your custom replacement.
Deploying Your Custom Replacement Script
Now create your custom replacement script at the original file location:
sudo tee /usr/bin/update-motd << 'EOF'
#!/bin/bash
# Custom enterprise MOTD wrapper
echo "[ALERT] Monitored Production Server - Unauthorized Access Prohibited"
# Call the original vendor binary if desired
/usr/bin/update-motd.distrib "$@"
EOF
sudo chmod 755 /usr/bin/update-motd
Whenever APT installs updates to update-motd, the new upstream version writes cleanly to update-motd.distrib, preserving your wrapper script indefinitely.
Restricting Diversions to Specific Packages
By default, dpkg-divert applies diversions across all packages. If you want a diversion to apply only when a specific package is installed, while allowing other packages or local builds to write to the default path, specify the --package switch:
sudo dpkg-divert --package base-files --divert /etc/issue.distrib --rename /etc/issue
To create a local diversion that overrides all packages, omit --package or specify --local (the default behavior).
Removing a Diversion and Restoring Original Files
When you no longer need the custom override and wish to restore default upstream package behavior:
First, remove your custom replacement file:
sudo rm /usr/bin/update-motd
Next, remove the diversion entry and restore the original package-managed file to its designated path:
sudo dpkg-divert --rename --remove /usr/bin/update-motd
The --rename flag automatically renames update-motd.distrib back to update-motd, returning the system to standard package management tracking.