#!/usr/bin/env bash # Verify dependencies for floppy-utils on Debian-based systems; optionally install via apt. set -euo pipefail INSTALL=0 QUIET=0 usage() { cat <<'EOF' Usage: check-deps.sh [OPTIONS] Check that base tools required by floppy-utils are available. On Debian, Ubuntu, Raspberry Pi OS, and derivatives, missing packages can be installed with apt when --install is passed. Options: --install, -i Install missing packages (requires apt and root/sudo) --quiet, -q Only print errors and the install command -h, --help Show this help Examples: ./check-deps.sh ./check-deps.sh --install sudo ./check-deps.sh -i EOF } while [[ $# -gt 0 ]]; do case "$1" in --install|-i) INSTALL=1; shift ;; --quiet|-q) QUIET=1; shift ;; -h|--help) usage; exit 0 ;; *) echo "check-deps.sh: unknown option: $1" >&2; usage >&2; exit 2 ;; esac done log() { if [[ "$QUIET" -eq 0 ]]; then echo "$@" fi return 0 } warn() { echo "check-deps.sh: $*" >&2 return 0 } die() { warn "$*" exit 1 } is_debian_like() { if [[ -f /etc/debian_version ]]; then return 0 fi if [[ -f /etc/os-release ]]; then # shellcheck source=/dev/null source /etc/os-release case "${ID:-}:${ID_LIKE:-}" in debian:*|*debian*|ubuntu:*|*ubuntu*|raspbian:*|linuxmint:*|pop:*|elementary:*|kali:*|devuan:*) return 0 ;; esac fi return 1 } os_description() { if [[ -f /etc/os-release ]]; then # shellcheck source=/dev/null source /etc/os-release printf '%s %s\n' "${NAME:-Linux}" "${VERSION_ID:-}" elif [[ -f /etc/debian_version ]]; then printf 'Debian %s\n' "$(cat /etc/debian_version)" else echo "Unknown" fi } # command -> Debian package providing it declare -A CMD_PKG=( [lsblk]=util-linux [blockdev]=util-linux [losetup]=util-linux [findmnt]=util-linux [fdisk]=util-linux [blkid]=util-linux [mount]=mount [umount]=mount [dd]=coreutils [readlink]=coreutils [mkfs.vfat]=dosfstools [sudo]=sudo [udisksctl]=udisks2 [udevadm]=udev [eject]=eject ) REQUIRED_CMDS=( lsblk blockdev losetup findmnt blkid mount umount dd readlink mkfs.vfat ) RECOMMENDED_CMDS=( sudo udisksctl udevadm eject fdisk ) have_cmd() { command -v "$1" >/dev/null 2>&1 } packages_for_cmds() { local -A seen=() local cmd pkg for cmd in "$@"; do pkg="${CMD_PKG[$cmd]:-}" [[ -n "$pkg" && -z "${seen[$pkg]:-}" ]] || continue seen[$pkg]=1 printf '%s\n' "$pkg" done } check_cmds() { local label="$1" local required="$2" shift 2 local cmd local -a missing=() log "$label" for cmd in "$@"; do if have_cmd "$cmd"; then log " OK $cmd" else if [[ "$required" -eq 1 ]]; then log " MISS $cmd (required)" else log " MISS $cmd (recommended)" fi missing+=("$cmd") fi done log "" MISSING_RESULT=("${missing[@]}") } run_apt_install() { local -a packages=("$@") [[ ${#packages[@]} -gt 0 ]] || return 0 if ! command -v apt-get >/dev/null 2>&1; then die "apt-get not found; install manually: ${packages[*]}" fi local -a apt_cmd=(apt-get) if [[ "$(id -u)" -ne 0 ]]; then command -v sudo >/dev/null 2>&1 || die "root or sudo required to install: ${packages[*]}" apt_cmd=(sudo apt-get) fi log "Installing: ${packages[*]}" "${apt_cmd[@]}" update -qq DEBIAN_FRONTEND=noninteractive "${apt_cmd[@]}" install -y --no-install-recommends "${packages[@]}" } main() { local -a missing_required=() missing_recommended=() packages=() local debian=0 log "floppy-utils dependency check" log "OS: $(os_description)" if is_debian_like; then debian=1 log "Debian-based system detected." else warn "Not a Debian-based system — will check commands only (no apt install)." fi log "" check_cmds "Required commands:" 1 "${REQUIRED_CMDS[@]}" missing_required=("${MISSING_RESULT[@]}") check_cmds "Recommended commands:" 0 "${RECOMMENDED_CMDS[@]}" missing_recommended=("${MISSING_RESULT[@]}") if [[ ${#missing_required[@]} -eq 0 && ${#missing_recommended[@]} -eq 0 ]]; then log "All required and recommended commands are available." exit 0 fi if [[ ${#missing_required[@]} -gt 0 ]]; then log "Missing required: ${missing_required[*]}" fi if [[ ${#missing_recommended[@]} -gt 0 ]]; then log "Missing recommended: ${missing_recommended[*]}" fi mapfile -t packages < <(packages_for_cmds "${missing_required[@]}" "${missing_recommended[@]}") if [[ ${#packages[@]} -gt 0 ]]; then log "Debian packages: ${packages[*]}" fi if [[ "$INSTALL" -eq 1 ]]; then [[ "$debian" -eq 1 ]] || die "refusing --install on non-Debian system" run_apt_install "${packages[@]}" log "" log "Re-checking..." INSTALL=0 main return fi if [[ "$debian" -eq 1 && ${#packages[@]} -gt 0 ]]; then log "" log "To install:" log " sudo ./check-deps.sh --install" log " # or: sudo apt-get install -y ${packages[*]}" fi if [[ ${#missing_required[@]} -gt 0 ]]; then die "required dependencies missing" fi warn "recommended tools missing — floppy-utils works with reduced functionality" exit 0 } main