Skip to content

Instantly share code, notes, and snippets.

@Raiu
Last active January 25, 2025 07:18
Show Gist options
  • Save Raiu/504e91365e9d6b3b5c47c8752b212858 to your computer and use it in GitHub Desktop.
Save Raiu/504e91365e9d6b3b5c47c8752b212858 to your computer and use it in GitHub Desktop.
Install essential packages for remote machine
#!/bin/sh
# Minimal Linux Package Management Setup Script
# POSIX-compliant and compatible with Ubuntu, Debian, Alpine, Rocky Linux, and Arch.
#
# sudo sh -c "$(curl -fsSL https://gist.githubusercontent.com/Raiu/504e91365e9d6b3b5c47c8752b212858/raw/packages.sh)"
#
set -e
log() { [ "$QUIET" -ne 1 ] && echo "$@"; }
error() { echo "Error: $*" >&2 && exit 1; }
exist() { type "$1" >/dev/null 2>&1; }
DEBIAN_UBUNTU="curl iputils-ping mtr nmap net-tools openssh-server rsync wget rar tree unzip unrar zip zoxide htop jq lshw mc screen tmux ca-certificates gnupg apt-transport-https apt-utils lsb-release software-properties-common git python3 python3-pip moreutils vim bash zsh sudo"
ALPINE="curl iputils mtr nmap net-tools openssh rsync wget rar tree unzip unrar zip zoxide htop jq lshw mc screen tmux ca-certificates gnupg alpine-sdk moreutils git python3 py3-pip vim bash doas shadow zsh"
ROCKY="curl iputils mtr nmap net-tools openssh-server rsync wget rar tree unzip unrar zip zoxide htop jq lshw mc screen tmux ca-certificates gnupg moreutils yum-utils gcc git make python3 python3-pip vim bash sudo zsh"
ARCH="curl iputils mtr nmap net-tools openssh rsync wget rar tree unzip unrar zip zoxide htop jq lshw mc screen tmux ca-certificates gnupg base-devel moreutils git python python-pip vim bash sudo zsh"
usage() {
cat <<EOF
Usage: $(basename "$0") [OPTIONS] [PACKAGES...]
Options:
-q, --quiet Suppress output (silent mode).
-p, --packages <packages> Specify custom packages as a quoted string.
-h, --help Display this help message and exit.
Examples:
$(basename "$0") # Install default packages.
$(basename "$0") -q # Quiet mode with default packages.
$(basename "$0") curl wget vim # Install specific packages.
$(basename "$0") -p "curl wget" # Use quoted string for custom packages.
$(basename "$0") -q curl wget vim # Quiet mode with custom packages.
EOF
exit 0
}
get_distro() {
[ ! -f "/etc/os-release" ] && error "/etc/os-release does not exist."
distro_id=$(grep "^ID=" /etc/os-release | cut -d= -f2 | awk '{print tolower($0)}')
[ -z "$distro_id" ] && error 'ID field not found in /etc/os-release.'
printf '%s' "$distro_id"
}
can_escalate() { command -v "$1" >/dev/null 2>&1 && "$1" -n true 2>/dev/null; }
setup_privileges() {
[ "$(id -u)" -eq 0 ] && return 0
for cmd in sudo doas; do
if can_escalate "$cmd"; then
SUDO="$cmd"
return 0
fi
done
error "Neither sudo nor doas found or accessible. Please run as root or install sudo/doas."
}
install_apt() {
DEBNI="DEBIAN_FRONTEND=noninteractive"
NOREC="--no-install-recommends --no-install-suggests"
if [ "$DISTRO" = "ubuntu" ]; then
$SUDO apt-add-repository -y universe restricted multiverse >/dev/null
elif [ "$DISTRO" = "debian" ]; then
if ! grep -q "contrib" /etc/apt/sources.list; then
$SUDO sh -c "sed -i '/^deb / s/$/ contrib/' /etc/apt/sources.list"
fi
if ! grep -q "non-free" /etc/apt/sources.list; then
$SUDO sh -c "sed -i '/^deb / s/$/ non-free/' /etc/apt/sources.list"
fi
if ! grep -q "non-free-firmware" /etc/apt/sources.list; then
$SUDO sh -c "sed -i '/^deb / s/$/ non-free-firmware/' /etc/apt/sources.list"
fi
fi
$SUDO sh -c "apt-get update >/dev/null && apt-get upgrade -y >/dev/null"
log " * Installing packages..."
for pkg in $DEBIAN_UBUNTU; do
log " - Installing $pkg"
$SUDO sh -c "$DEBNI apt-get install -y $NOREC $pkg >/dev/null" || error "Failed to install $pkg on APT-based systems."
done
$SUDO sh -c "apt-get autoremove -y >/dev/null && apt-get clean -y >/dev/null"
}
install_alpine() {
log " * Updating Alpine repositories..."
$SUDO sh -c "apk update -q >/dev/null" || error "Failed to update Alpine repositories."
log " * Upgrading Alpine packages..."
$SUDO sh -c "apk upgrade -q --no-interactive >/dev/null" || error "Failed to upgrade Alpine packages."
log " * Installing packages..."
for pkg in $ALPINE; do
log " - Installing $pkg"
$SUDO sh -c "apk add -q --no-interactive $pkg >/dev/null" || error "Failed to install $pkg on Alpine."
done
$SUDO sh -c "apk cache clean >/dev/null" || error "Failed to clean up Alpine package cache."
}
install_rpm() {
log " * Updating RHEL-based repositories..."
$SUDO sh -c "dnf makecache -q >/dev/null" || error "Failed to update RPM-based repositories."
$SUDO sh -c "dnf upgrade -y -q >/dev/null" || error "Failed to upgrade RPM-based packages."
log " * Installing packages..."
for pkg in $ROCKY; do
log " - Installing $pkg"
$SUDO sh -c "dnf install -y -q $pkg >/dev/null" || error "Failed to install $pkg on RHEL-based systems."
done
$SUDO sh -c "dnf autoremove -y -q >/dev/null && dnf clean all >/dev/null" || error "Failed to clean up RPM package manager."
}
install_arch() {
log " * Updating Arch/Manjaro repositories..."
$SUDO sh -c "pacman -Sy --noconfirm --quiet >/dev/null" || error "Failed to update Arch/Manjaro repositories."
log " * Installing packages..."
for pkg in $ARCH; do
log " - Installing $pkg"
$SUDO sh -c "pacman -S --noconfirm --quiet $pkg >/dev/null" || error "Failed to install $pkg on Arch-based systems."
done
$SUDO sh -c "pacman -Sc --noconfirm >/dev/null" || error "Failed to clean up Arch package manager."
}
process_packages() {
case "$DISTRO" in
ubuntu | debian) install_apt ;;
alpine) install_alpine ;;
rocky | centos | fedora | rhel) install_rpm ;;
arch | manjaro) install_arch ;;
*) error "Unsupported distribution: $DISTRO" ;;
esac
}
main() {
QUIET=0
CUSTOM=""
DISTRO=$(get_distro)
while [ "$#" -gt 0 ]; do
case "$1" in
-q | --quiet) QUIET=1 ;;
-p | --packages)
shift
CUSTOM="$1"
;;
-h | --help) usage ;;
-*) error "Invalid argument: $1. Use -h or --help for usage information." ;;
*) CUSTOM="$CUSTOM $1" ;;
esac
shift
done
log "Starting package management setup..."
log " * Verifying privileges..."
setup_privileges
process_packages
log "Setup complete! Packages installed successfully."
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment