Make a script work on both families
Task
Write a single script that installs and starts a web server, and works unchanged on both a RHEL-family and a Debian-family system. It must detect the family from the machine rather than being told, use the right package manager, account for the package having a different name on each, and leave the service enabled at boot.
This is the applied form of the family-to-command mapping, and it is the shape of every real portability problem you will meet.
Steps
- Detect the family by sourcing
/etc/os-releaseand branching onIDandID_LIKE, not on the presence of a command. Handle the case where neither matches by exiting non-zero with a clear message. - Map the family to its package manager and to the web server's package name. On the Red Hat side the package is
httpd; on the Debian side it isapache2. The service unit differs with it. - Remember that
aptneeds its metadata refreshed first anddnfdoes not. - Install the package, then enable and start the service in one command.
- Make the script idempotent: running it twice must succeed and change nothing the second time.
- Run it on both machines and confirm the web server answers.
Verify
# on each machine, after running the script twice
systemctl is-enabled httpd 2>/dev/null || systemctl is-enabled apache2
systemctl is-active httpd 2>/dev/null || systemctl is-active apache2
curl -sf -o /dev/null -w '%{http_code}\n' http://localhost/
All three must succeed on both systems: enabled, active, and 200. Then run the script a second time and confirm its exit status is still 0 -- a script that fails on the second run is not idempotent, and will break the first time it is used from configuration management.
Notes
The temptation is to detect the family by testing for the dnf binary. That works until you meet a Debian machine with dnf installed for some other reason. Read what the system says it is.