#!/usr/bin/env bash # install-discord.sh — Install Discord from the latest official Linux .deb. # Hardened: official latest endpoint, idempotent, --dry-run. set -euo pipefail IFS=$'\n\t' readonly SCRIPT_NAME="${0##*/}" DRY_RUN=0 DOWNLOAD_URL="https://discord.com/api/download?platform=linux&format=deb" usage() { cat <&2; exit 1; } run() { if (( DRY_RUN )); then printf ' DRY-RUN: %s\n' "$*"; else eval "$@"; fi; } trap 'rc=$?; (( rc )) && printf "\033[1;31m[%s] failed at line %s (exit %d)\033[0m\n" "${SCRIPT_NAME%.sh}" "$LINENO" "$rc" >&2' ERR while (( $# )); do case "$1" in --dry-run) DRY_RUN=1 ;; -h|--help) usage; exit 0 ;; *) die "Unknown argument: $1 (try --help)" ;; esac shift done (( EUID == 0 )) || die "Must run as root. Try: sudo $SCRIPT_NAME" [[ -r /etc/os-release ]] || die "/etc/os-release not found." # shellcheck disable=SC1091 . /etc/os-release case "${ID:-}:${ID_LIKE:-}" in *ubuntu*|*debian*) : ;; *) die "Unsupported distro: ${PRETTY_NAME:-unknown}." ;; esac ARCH="$(dpkg --print-architecture)" [[ "$ARCH" == "amd64" ]] || die "Discord's official Linux .deb targets amd64 only (detected: $ARCH)." log "Detected: ${PRETTY_NAME:-unknown}, arch: $ARCH" export DEBIAN_FRONTEND=noninteractive log "Installing prerequisites..." run "apt-get update -qq" run "apt-get install -y curl ca-certificates" STAGE="$(mktemp -d -t discord.XXXXXX)" trap 'rm -rf "$STAGE"' EXIT DEB="$STAGE/discord.deb" log "Downloading latest Discord .deb..." run "curl -fL -o '$DEB' '$DOWNLOAD_URL'" if (( DRY_RUN )); then printf ' DRY-RUN: apt-get install -y %s\n' "$DEB" log "Done." exit 0 fi log "Installing Discord..." run "apt-get install -y '$DEB'" if command -v discord >/dev/null 2>&1; then log "Installed: $(discord --version 2>/dev/null || dpkg-query -W -f='${Version}' discord 2>/dev/null || echo Discord)" else log "Installed: $(dpkg-query -W -f='${Version}' discord 2>/dev/null || echo Discord)" fi log "Done."