390 lines
16 KiB
Bash
390 lines
16 KiB
Bash
#!/bin/bash
|
|
# ═══════════════════════════════════════════════════════════════════
|
|
# apps.sh — edemilov universal app installer
|
|
# Arch / CachyOS / Parrot / Kali / Debian / Ubuntu
|
|
#
|
|
# curl -s https://git.edemilov.ru/edemilov/scripts/raw/branch/master/apps.sh | sudo bash
|
|
# ═══════════════════════════════════════════════════════════════════
|
|
|
|
set -e
|
|
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
|
|
CYAN='\033[0;36m'; MAGENTA='\033[0;35m'; BOLD='\033[1m'; NC='\033[0m'
|
|
info() { echo -e "${CYAN}[•]${NC} $1"; }
|
|
success() { echo -e "${GREEN}[✓]${NC} $1"; }
|
|
warn() { echo -e "${YELLOW}[!]${NC} $1"; }
|
|
skip() { echo -e "${MAGENTA}[~]${NC} $1 (already installed)"; }
|
|
die() { echo -e "${RED}[✗]${NC} $1"; exit 1; }
|
|
header() { echo -e "\n${BOLD}${CYAN}── $1 ──────────────────────────────${NC}"; }
|
|
|
|
echo -e "${BOLD}"
|
|
echo " ╔══════════════════════════════════════════════╗"
|
|
echo " ║ apps.sh — edemilov universal installer ║"
|
|
echo " ╚══════════════════════════════════════════════╝"
|
|
echo -e "${NC}"
|
|
|
|
# ── Detect distro ─────────────────────────────────────────────────
|
|
header "Detecting system"
|
|
[[ -f /etc/os-release ]] && . /etc/os-release || die "Cannot detect distro"
|
|
DISTRO_ID="${ID,,}"
|
|
DISTRO_LIKE="${ID_LIKE,,}"
|
|
info "Distro: ${PRETTY_NAME}"
|
|
|
|
if command -v pacman &>/dev/null; then
|
|
FAMILY="arch"
|
|
elif [[ "$DISTRO_ID" =~ ^(kali|parrot|debian|ubuntu|linuxmint|pop)$ ]] || \
|
|
[[ "$DISTRO_LIKE" =~ debian ]] || [[ "$DISTRO_LIKE" =~ ubuntu ]]; then
|
|
FAMILY="debian"
|
|
elif command -v dnf &>/dev/null; then
|
|
FAMILY="fedora"
|
|
else
|
|
die "Unsupported distro: $DISTRO_ID"
|
|
fi
|
|
info "Family: $FAMILY"
|
|
|
|
# Real user (even when run with sudo)
|
|
REAL_USER="${SUDO_USER:-$(logname 2>/dev/null || echo $USER)}"
|
|
REAL_HOME=$(eval echo ~$REAL_USER)
|
|
info "User: $REAL_USER ($REAL_HOME)"
|
|
|
|
# ── Package manager setup ─────────────────────────────────────────
|
|
case $FAMILY in
|
|
arch)
|
|
UPDATE_CMD="pacman -Syu --noconfirm"
|
|
INSTALL="pacman -S --noconfirm --needed"
|
|
IS_INSTALLED() { pacman -Qi "$1" &>/dev/null; }
|
|
# AUR helper
|
|
if command -v paru &>/dev/null; then
|
|
AUR="paru -S --noconfirm --needed"
|
|
elif command -v yay &>/dev/null; then
|
|
AUR="yay -S --noconfirm --needed"
|
|
else
|
|
AUR=""
|
|
fi
|
|
;;
|
|
debian)
|
|
UPDATE_CMD="apt-get update -qq"
|
|
INSTALL="apt-get install -y -qq"
|
|
IS_INSTALLED() { dpkg -l "$1" 2>/dev/null | grep -q "^ii"; }
|
|
$UPDATE_CMD
|
|
;;
|
|
fedora)
|
|
UPDATE_CMD="dnf check-update -q || true"
|
|
INSTALL="dnf install -y -q"
|
|
IS_INSTALLED() { rpm -q "$1" &>/dev/null; }
|
|
;;
|
|
esac
|
|
|
|
# Smart install wrapper
|
|
pkg() {
|
|
local name="$1" arch="$2" deb="${3:-$2}" fed="${4:-$2}"
|
|
local pkg
|
|
case $FAMILY in arch) pkg="$arch" ;; debian) pkg="$deb" ;; fedora) pkg="$fed" ;; esac
|
|
if IS_INSTALLED "$pkg" 2>/dev/null || command -v "$arch" &>/dev/null; then
|
|
skip "$name"
|
|
else
|
|
info "Installing $name..."
|
|
$INSTALL $pkg && success "$name" || warn "$name failed — skipping"
|
|
fi
|
|
}
|
|
|
|
# AUR install wrapper
|
|
aur() {
|
|
local name="$1" pkg="$2"
|
|
if IS_INSTALLED "$pkg" 2>/dev/null || command -v "$pkg" &>/dev/null; then
|
|
skip "$name"
|
|
elif [[ -n "$AUR" ]]; then
|
|
info "Installing $name (AUR)..."
|
|
su - "$REAL_USER" -c "$AUR $pkg" && success "$name" || warn "$name AUR failed"
|
|
else
|
|
warn "$name — no AUR helper found (install paru or yay first)"
|
|
fi
|
|
}
|
|
|
|
# ── Update ────────────────────────────────────────────────────────
|
|
header "Updating package database"
|
|
$UPDATE_CMD && success "Updated"
|
|
|
|
# ── Core tools ────────────────────────────────────────────────────
|
|
header "Core system tools"
|
|
pkg "git" "git"
|
|
pkg "curl" "curl"
|
|
pkg "wget" "wget"
|
|
pkg "htop" "htop"
|
|
pkg "btop" "btop"
|
|
pkg "tmux" "tmux"
|
|
pkg "neofetch" "neofetch"
|
|
pkg "tree" "tree"
|
|
pkg "jq" "jq"
|
|
pkg "unzip" "unzip"
|
|
pkg "rsync" "rsync"
|
|
pkg "nmap" "nmap"
|
|
pkg "net-tools" "net-tools"
|
|
pkg "cifs-utils" "cifs-utils"
|
|
pkg "smbclient" "samba" "smbclient"
|
|
|
|
# ── Shell ─────────────────────────────────────────────────────────
|
|
header "Shell"
|
|
pkg "zsh" "zsh"
|
|
|
|
# Set zsh as default for real user
|
|
if [[ "$(getent passwd $REAL_USER | cut -d: -f7)" != "$(which zsh)" ]]; then
|
|
info "Setting zsh as default shell for $REAL_USER..."
|
|
chsh -s "$(which zsh)" "$REAL_USER" && success "zsh set as default"
|
|
fi
|
|
|
|
# oh-my-zsh
|
|
if [[ ! -d "$REAL_HOME/.oh-my-zsh" ]]; then
|
|
info "Installing oh-my-zsh..."
|
|
su - "$REAL_USER" -c \
|
|
'sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended' \
|
|
&& success "oh-my-zsh" || warn "oh-my-zsh failed"
|
|
else
|
|
skip "oh-my-zsh"
|
|
fi
|
|
|
|
# ── Dev tools ─────────────────────────────────────────────────────
|
|
header "Development tools"
|
|
pkg "python3" "python3"
|
|
pkg "pip" "python-pip" "python3-pip"
|
|
pkg "nodejs" "nodejs"
|
|
pkg "npm" "npm"
|
|
pkg "git" "git"
|
|
|
|
# ── Docker ────────────────────────────────────────────────────────
|
|
header "Docker"
|
|
if command -v docker &>/dev/null; then
|
|
skip "Docker"
|
|
else
|
|
case $FAMILY in
|
|
arch) $INSTALL docker docker-compose; systemctl enable --now docker ;;
|
|
debian) curl -fsSL https://get.docker.com | sh ;;
|
|
fedora) $INSTALL docker-ce docker-ce-cli containerd.io; systemctl enable --now docker ;;
|
|
esac
|
|
usermod -aG docker "$REAL_USER" 2>/dev/null && success "Docker (user added to group)"
|
|
fi
|
|
|
|
# ── VS Code ───────────────────────────────────────────────────────
|
|
header "VS Code"
|
|
if command -v code &>/dev/null; then
|
|
skip "VS Code"
|
|
else
|
|
case $FAMILY in
|
|
arch)
|
|
aur "VS Code" "visual-studio-code-bin"
|
|
;;
|
|
debian)
|
|
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | \
|
|
gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg
|
|
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] \
|
|
https://packages.microsoft.com/repos/vscode stable main" \
|
|
> /etc/apt/sources.list.d/vscode.list
|
|
apt-get update -qq && $INSTALL code && success "VS Code"
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
# ── Browsers ──────────────────────────────────────────────────────
|
|
header "Browsers"
|
|
case $FAMILY in
|
|
arch)
|
|
pkg "Chromium" "chromium"
|
|
pkg "Brave" "brave-bin" || aur "Brave" "brave-bin"
|
|
;;
|
|
debian)
|
|
pkg "Chromium" "chromium" "chromium"
|
|
# Brave on debian
|
|
if ! command -v brave-browser &>/dev/null; then
|
|
info "Installing Brave..."
|
|
curl -fsSLo /usr/share/keyrings/brave-browser-archive-keyring.gpg \
|
|
https://brave-keyring.s3.brave.com/brave-browser-archive-keyring.gpg
|
|
echo "deb [signed-by=/usr/share/keyrings/brave-browser-archive-keyring.gpg] \
|
|
https://brave-browser-apt-release.s3.brave.com/ stable main" \
|
|
> /etc/apt/sources.list.d/brave-browser-release.list
|
|
apt-get update -qq && $INSTALL brave-browser && success "Brave"
|
|
else
|
|
skip "Brave"
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
# ── Communication ─────────────────────────────────────────────────
|
|
header "Communication"
|
|
case $FAMILY in
|
|
arch)
|
|
pkg "Discord" "discord"
|
|
pkg "Telegram" "telegram-desktop"
|
|
# WhatsApp — web app via Chromium, no native package needed
|
|
;;
|
|
debian)
|
|
# Discord
|
|
if ! command -v discord &>/dev/null; then
|
|
info "Installing Discord..."
|
|
wget -qO /tmp/discord.deb "https://discord.com/api/download?platform=linux&format=deb"
|
|
dpkg -i /tmp/discord.deb || apt-get install -f -y
|
|
success "Discord"
|
|
else
|
|
skip "Discord"
|
|
fi
|
|
pkg "Telegram" "telegram-desktop" "telegram-desktop"
|
|
;;
|
|
esac
|
|
|
|
# ── Media & Gaming ────────────────────────────────────────────────
|
|
header "Media & Gaming"
|
|
case $FAMILY in
|
|
arch)
|
|
pkg "Steam" "steam"
|
|
pkg "Heroic Games" "heroic-games-launcher-bin" || aur "Heroic" "heroic-games-launcher-bin"
|
|
pkg "qBittorrent" "qbittorrent"
|
|
pkg "VLC" "vlc"
|
|
pkg "Strawberry" "strawberry"
|
|
;;
|
|
debian)
|
|
# Steam
|
|
if ! command -v steam &>/dev/null; then
|
|
dpkg --add-architecture i386
|
|
apt-get update -qq
|
|
$INSTALL steam-installer && success "Steam"
|
|
else
|
|
skip "Steam"
|
|
fi
|
|
pkg "qBittorrent" "qbittorrent" "qbittorrent"
|
|
pkg "VLC" "vlc" "vlc"
|
|
;;
|
|
esac
|
|
|
|
# ── Wine / Windows apps ───────────────────────────────────────────
|
|
header "Wine (Windows compatibility)"
|
|
case $FAMILY in
|
|
arch)
|
|
if ! command -v wine &>/dev/null; then
|
|
info "Installing Wine + Winboat deps..."
|
|
$INSTALL wine wine-mono winetricks
|
|
aur "Winboat" "winboat"
|
|
success "Wine + Winboat"
|
|
else
|
|
skip "Wine"
|
|
fi
|
|
;;
|
|
debian)
|
|
if ! command -v wine &>/dev/null; then
|
|
dpkg --add-architecture i386
|
|
apt-get update -qq
|
|
$INSTALL wine winetricks && success "Wine"
|
|
else
|
|
skip "Wine"
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
# ── Virtualisation ────────────────────────────────────────────────
|
|
header "Virtualisation"
|
|
case $FAMILY in
|
|
arch)
|
|
if ! command -v virt-manager &>/dev/null; then
|
|
$INSTALL virt-manager qemu-full libvirt dnsmasq
|
|
systemctl enable --now libvirtd
|
|
usermod -aG libvirt "$REAL_USER"
|
|
success "virt-manager + QEMU"
|
|
else
|
|
skip "virt-manager"
|
|
fi
|
|
;;
|
|
debian)
|
|
if ! command -v virt-manager &>/dev/null; then
|
|
$INSTALL virt-manager qemu-kvm libvirt-daemon-system
|
|
systemctl enable --now libvirtd
|
|
usermod -aG libvirt "$REAL_USER"
|
|
success "virt-manager"
|
|
else
|
|
skip "virt-manager"
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
# ── Cloud & sync ──────────────────────────────────────────────────
|
|
header "Cloud & sync"
|
|
case $FAMILY in
|
|
arch)
|
|
pkg "Nextcloud client" "nextcloud-client"
|
|
pkg "Bitwarden" "bitwarden"
|
|
;;
|
|
debian)
|
|
# Nextcloud
|
|
if ! command -v nextcloud &>/dev/null; then
|
|
$INSTALL nextcloud-desktop && success "Nextcloud" || warn "Nextcloud not in repos — install from flatpak"
|
|
else
|
|
skip "Nextcloud"
|
|
fi
|
|
# Bitwarden
|
|
if ! command -v bitwarden &>/dev/null; then
|
|
wget -qO /tmp/bitwarden.deb \
|
|
"https://vault.bitwarden.com/download/?app=desktop&platform=linux&variant=deb"
|
|
dpkg -i /tmp/bitwarden.deb && success "Bitwarden" || warn "Bitwarden install failed"
|
|
else
|
|
skip "Bitwarden"
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
# ── Network tools ─────────────────────────────────────────────────
|
|
header "Network tools"
|
|
pkg "nmap" "nmap"
|
|
pkg "wireshark" "wireshark-qt" "wireshark"
|
|
pkg "traceroute" "traceroute"
|
|
pkg "whois" "whois"
|
|
|
|
# Kali/Parrot extras
|
|
if [[ "$DISTRO_ID" =~ ^(kali|parrot)$ ]]; then
|
|
header "Pentesting extras"
|
|
pkg "gobuster" "gobuster" "gobuster"
|
|
pkg "ffuf" "ffuf" "ffuf"
|
|
fi
|
|
|
|
# ── Flatpak ───────────────────────────────────────────────────────
|
|
header "Flatpak"
|
|
if [[ "$FAMILY" != "arch" ]]; then
|
|
pkg "flatpak" "flatpak"
|
|
if ! flatpak remotes | grep -q flathub; then
|
|
flatpak remote-add --if-not-exists flathub \
|
|
https://dl.flathub.org/repo/flathub.flatpakrepo
|
|
success "Flathub added"
|
|
else
|
|
skip "Flathub"
|
|
fi
|
|
fi
|
|
|
|
# ── Tailscale ─────────────────────────────────────────────────────
|
|
header "Tailscale"
|
|
if ! command -v tailscale &>/dev/null; then
|
|
case $FAMILY in
|
|
arch) $INSTALL tailscale; systemctl enable --now tailscaled ;;
|
|
debian) curl -fsSL https://tailscale.com/install.sh | sh ;;
|
|
esac
|
|
success "Tailscale — run: sudo tailscale up"
|
|
else
|
|
skip "Tailscale"
|
|
fi
|
|
|
|
# ── Cleanup ───────────────────────────────────────────────────────
|
|
header "Cleanup"
|
|
case $FAMILY in
|
|
arch) pacman -Sc --noconfirm &>/dev/null ;;
|
|
debian) apt-get autoremove -y -qq && apt-get clean -qq ;;
|
|
fedora) dnf clean all -q ;;
|
|
esac
|
|
success "Cache cleaned"
|
|
|
|
# ── Done ──────────────────────────────────────────────────────────
|
|
echo ""
|
|
echo -e "${BOLD}${GREEN}═══════════════════════════════════════════════════${NC}"
|
|
echo -e "${BOLD} ✓ apps.sh complete!${NC}"
|
|
echo -e "${GREEN}═══════════════════════════════════════════════════${NC}"
|
|
echo ""
|
|
echo -e " ${CYAN}Next steps:${NC}"
|
|
echo -e " ${YELLOW}bash <(curl -s https://git.edemilov.ru/edemilov/scripts/raw/branch/master/netdrivelink.sh)${NC}"
|
|
echo -e " ${YELLOW}git clone https://git.edemilov.ru/edemilov/dotfiles.git ~/dotfiles && bash ~/dotfiles/install.sh${NC}"
|
|
echo ""
|
|
echo -e " ${CYAN}Log out and back in for:${NC} docker group, zsh default, libvirt group"
|
|
echo ""
|