Skip to content

Instantly share code, notes, and snippets.

@lgallindo
Created August 24, 2026 04:29
Show Gist options
  • Select an option

  • Save lgallindo/7334431f3554b58058fcf99f697e2f9e to your computer and use it in GitHub Desktop.

Select an option

Save lgallindo/7334431f3554b58058fcf99f697e2f9e to your computer and use it in GitHub Desktop.
HPLIP on Lux Linux: spoof as Debian 12 (+ sudo)
#!/usr/bin/env bash
# Patch extracted HPLIP so Lux Linux is treated as Debian 12 (with sudo).
# Usage: hplip-lux-debian-spoof [/path/to/hplip-VERSION]
set -euo pipefail
ROOT="${1:-}"
if [[ -z "$ROOT" ]]; then
if [[ -d ./base && -f ./installer/distros.dat ]]; then
ROOT=$PWD
else
echo "Usage: $0 /path/to/hplip-3.26.4" >&2
exit 2
fi
fi
ROOT=$(cd "$ROOT" && pwd)
UTILS="$ROOT/base/utils.py"
DISTROS="$ROOT/installer/distros.dat"
[[ -f "$UTILS" && -f "$DISTROS" ]] || { echo "Not an HPLIP source tree: $ROOT" >&2; exit 1; }
python3 - "$UTILS" <<'PY'
from pathlib import Path
import sys
p = Path(sys.argv[1])
text = p.read_text()
marker = "HPLIP_LUX_DEBIAN_SPOOF"
if marker in text:
print("utils.py already patched")
else:
old = 'def get_distro_name(passwordObj = None):\n log.debug("Determining distro...")\n'
new = (
"def get_distro_name(passwordObj = None):\n"
f" # {marker}: Lux is Debian-based but not in HPLIP distros.dat — report Debian 12.\n"
" try:\n"
" import distro as _distro\n"
' if _distro.id() == "lux" or "lux" in (_distro.name() or "").lower():\n'
' log.debug("Lux detected; spoofing distro as debian 12 for HPLIP installer")\n'
' return ("debian", "12")\n'
" except Exception:\n"
" pass\n"
' log.debug("Determining distro...")\n'
)
if old not in text:
raise SystemExit("utils.py needle not found — HPLIP layout changed?")
p.write_text(text.replace(old, new, 1))
print("patched", p)
PY
python3 - "$DISTROS" <<'PY'
from pathlib import Path
import re, sys
p = Path(sys.argv[1])
text = p.read_text()
marker = "# HPLIP_LUX_DEBIAN_SUDO"
if marker in text:
print("distros.dat already patched")
raise SystemExit(0)
m = re.search(r"^\[debian\]\n(.*?)(?=^\[(?!debian:))", text, re.M | re.S)
if not m:
raise SystemExit("debian section not found")
sec = m.group(0)
new = sec
new = new.replace("su_sudo=su", "su_sudo=sudo")
new = new.replace(
'package_mgr_cmd=su -c "apt-get install --force-yes -y $packages_to_install"',
"package_mgr_cmd=sudo apt-get install --assume-yes $packages_to_install",
)
new = new.replace(
'pre_depend_cmd=su -c "dpkg --configure -a",su -c "apt-get install -f",su -c "apt-get update"',
"pre_depend_cmd=sudo dpkg --configure -a,sudo apt-get install -f,sudo apt-get update",
)
new = new.replace(
'hp_libs_remove_cmd= su -c "apt-get remove libhpmud0 libsane-hpaio printer-driver-postscript-hp"',
"hp_libs_remove_cmd=sudo apt-get remove --assume-yes libhpmud0 libsane-hpaio printer-driver-postscript-hp",
)
new = new.replace(
'hplip_remove_cmd=su -c "apt-get remove --yes hplip hpijs hplip-data"',
"hplip_remove_cmd=sudo apt-get remove --assume-yes hplip hpijs hplip-data",
)
new = re.sub(r'su -c "([^"]+)"', r"sudo \1", new)
if new == sec:
raise SystemExit("no changes made to debian section")
p.write_text(text[: m.start()] + marker + "\n" + new + text[m.end() :])
print("patched", p)
PY
echo "OK: $ROOT now reports Lux as Debian 12 (sudo). Next:"
echo " cd \"$ROOT\" && ./hplip-install"

HPLIP on Lux Linux: pretend Debian 12

Lux (ID=lux, ID_LIKE=debian) is not in HPLIP’s distros.dat, so the official .run installer aborts with unknown distro. After extracting the tarball, patch the tree so Lux is reported as Debian 12, and switch the Debian recipe from su to sudo (Lux desktops use sudo).

Quick patch (extracted hplip-3.26.4/)

# 1) Lux → Debian 12
python3 - <<'PY'
from pathlib import Path
p = Path("base/utils.py")
t = p.read_text()
old = 'def get_distro_name(passwordObj = None):\n    log.debug("Determining distro...")\n'
new = '''def get_distro_name(passwordObj = None):
    try:
        import distro as _d
        if _d.id() == "lux" or "lux" in (_d.name() or "").lower():
            return ("debian", "12")
    except Exception:
        pass
    log.debug("Determining distro...")
'''
assert old in t
p.write_text(t.replace(old, new, 1))
print("patched", p)
PY

# 2) Debian profile: su → sudo
python3 - <<'PY'
from pathlib import Path
import re
p = Path("installer/distros.dat")
t = p.read_text()
m = re.search(r"^\[debian\]\n(.*?)(?=^\[(?!debian:))", t, re.M | re.S)
sec = m.group(0)
new = sec.replace("su_sudo=su", "su_sudo=sudo")
new = re.sub(r'su -c "([^"]+)"', r"sudo \1", new)
new = new.replace(
    'package_mgr_cmd=su -c "apt-get install --force-yes -y $packages_to_install"',
    "package_mgr_cmd=sudo apt-get install --assume-yes $packages_to_install",
)
p.write_text(t[: m.start()] + new + t[m.end() :])
print("patched", p)
PY

./hplip-install

Or use the registered helper: hplip-lux-debian-spoof /path/to/hplip-3.26.4

Notes

  • HPLIP’s Debian list stops at 12; Lux 2 is Debian 13–based (trixie), so spoofing 12 is intentional.
  • On recent GCC/Python, the interactive installer may still fail at compile time; a ./configure && make && sudo make install path with permissive CFLAGS (and optionally --disable-scan-build if you already use sane-airscan) is more reliable.
  • Driverless IPP + sane-airscan often already print/scan HP Smart Tank 580–590 without HPLIP; this hack is for native HPLIP / newer model tables (e.g. 3.26.4).

Tested on Lux 2 (Bellatrix) with HPLIP 3.26.4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment