Upload files to "/"
This commit is contained in:
BIN
ZSH StianNOR install.png
Normal file
BIN
ZSH StianNOR install.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 126 KiB |
459
uninstall.sh
Normal file
459
uninstall.sh
Normal file
@@ -0,0 +1,459 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# 🗑️ StianNOR — COMPLETE UNINSTALLER v1.0
|
||||||
|
# Uninstalls everything installed by:
|
||||||
|
# - setup_zsh_font.sh (Zsh, Oh My Zsh, p10k, plugins, colorls, fastfetch, Hack Nerd Font)
|
||||||
|
# - portainerup.sh (Portainer CE, Docker, Docker Compose)
|
||||||
|
# =============================================================================
|
||||||
|
set -uo pipefail
|
||||||
|
|
||||||
|
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'; CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m'
|
||||||
|
LINE="────────────────────────────────────────────────────────────────────────────"
|
||||||
|
|
||||||
|
info() { echo -e "${CYAN}ℹ $*${RESET}"; }
|
||||||
|
success() { echo -e "${GREEN}✅ $*${RESET}"; }
|
||||||
|
warn() { echo -e "${YELLOW}⚠ $*${RESET}"; }
|
||||||
|
error() { echo -e "${RED}❌ $*${RESET}"; }
|
||||||
|
step() { echo -e "\n${BOLD}${BLUE}➤ $*${RESET}"; echo -e "${BLUE}${LINE}${RESET}"; }
|
||||||
|
skip() { echo -e " ${BLUE}↷ $* — not found, skipping${RESET}"; }
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# DETECT PACKAGE MANAGER
|
||||||
|
# =============================================================================
|
||||||
|
detect_pm() {
|
||||||
|
if command -v pacman >/dev/null 2>&1; then PM="pacman"
|
||||||
|
elif command -v apt >/dev/null 2>&1; then PM="apt"
|
||||||
|
elif command -v dnf >/dev/null 2>&1; then PM="dnf"
|
||||||
|
elif command -v zypper >/dev/null 2>&1; then PM="zypper"
|
||||||
|
elif command -v apk >/dev/null 2>&1; then PM="apk"
|
||||||
|
else PM="unknown"; fi
|
||||||
|
}
|
||||||
|
detect_pm
|
||||||
|
|
||||||
|
pkg_remove() {
|
||||||
|
case "$PM" in
|
||||||
|
pacman) sudo pacman -Rns --noconfirm "$@" 2>/dev/null || true ;;
|
||||||
|
apt) sudo apt remove -y --purge "$@" 2>/dev/null || true; sudo apt autoremove -y 2>/dev/null || true ;;
|
||||||
|
dnf) sudo dnf remove -y "$@" 2>/dev/null || true ;;
|
||||||
|
zypper) sudo zypper remove -y "$@" 2>/dev/null || true ;;
|
||||||
|
apk) sudo apk del "$@" 2>/dev/null || true ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# CONFIRM — show full plan before doing anything
|
||||||
|
# =============================================================================
|
||||||
|
clear
|
||||||
|
echo -e "${LINE}"
|
||||||
|
echo -e "${BOLD}${RED} 🗑️ StianNOR COMPLETE UNINSTALLER${RESET}"
|
||||||
|
echo -e "${LINE}"
|
||||||
|
echo ""
|
||||||
|
echo -e " This will remove the following — ${BOLD}select what to uninstall:${RESET}"
|
||||||
|
echo ""
|
||||||
|
echo -e " ${BOLD}${CYAN}[A] ZSH + FONT SETUP${RESET}"
|
||||||
|
echo -e " • Hack Nerd Font (system-wide)"
|
||||||
|
echo -e " • fontconfig monospace alias (/etc/fonts/local.conf)"
|
||||||
|
echo -e " • Oh My Zsh + Powerlevel10k + all plugins"
|
||||||
|
echo -e " • colorls Ruby gem"
|
||||||
|
echo -e " • fastfetch"
|
||||||
|
echo -e " • ~/.zshrc and ~/.p10k.zsh"
|
||||||
|
echo -e " • Default shell reverted to bash"
|
||||||
|
echo ""
|
||||||
|
echo -e " ${BOLD}${CYAN}[B] PORTAINER + DOCKER${RESET}"
|
||||||
|
echo -e " • Portainer CE container + data volume"
|
||||||
|
echo -e " • Docker CE + Docker Compose"
|
||||||
|
echo -e " • docker group membership for $USER"
|
||||||
|
echo -e " • Docker config dir (~/.docker)"
|
||||||
|
echo ""
|
||||||
|
echo -e " ${BOLD}${CYAN}[C] BOTH (full wipe)${RESET}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${LINE}"
|
||||||
|
echo -e " ${YELLOW}[q]${RESET} cancel and exit"
|
||||||
|
echo -e "${LINE}"
|
||||||
|
echo ""
|
||||||
|
printf " Choice: "
|
||||||
|
read -r CHOICE
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
case "${CHOICE,,}" in
|
||||||
|
a) DO_ZSH=true; DO_DOCKER=false ;;
|
||||||
|
b) DO_ZSH=false; DO_DOCKER=true ;;
|
||||||
|
c) DO_ZSH=true; DO_DOCKER=true ;;
|
||||||
|
q|"") echo -e " ${YELLOW}Cancelled.${RESET}"; exit 0 ;;
|
||||||
|
*) echo -e " ${RED}Invalid choice. Exiting.${RESET}"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Final confirm
|
||||||
|
echo -e "${LINE}"
|
||||||
|
echo -e " ${BOLD}${RED}This is destructive and cannot be undone.${RESET}"
|
||||||
|
printf " Type ${BOLD}YES${RESET} to confirm: "
|
||||||
|
read -r CONFIRM
|
||||||
|
echo ""
|
||||||
|
[[ "$CONFIRM" != "YES" ]] && echo -e " ${YELLOW}Aborted.${RESET}" && exit 0
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# LOG FILE
|
||||||
|
# =============================================================================
|
||||||
|
LOG_DIR="$HOME/Homelab/logs"
|
||||||
|
mkdir -p "$LOG_DIR" 2>/dev/null || LOG_DIR="/tmp"
|
||||||
|
LOG_FILE="$LOG_DIR/uninstall-$(date +%Y%m%d-%H%M%S).log"
|
||||||
|
exec > >(tee -a "$LOG_FILE") 2>&1
|
||||||
|
info "Logging to $LOG_FILE"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# A — UNINSTALL ZSH + FONT SETUP
|
||||||
|
# =============================================================================
|
||||||
|
uninstall_zsh_font() {
|
||||||
|
|
||||||
|
# ── 1. Revert default shell to bash ──────────────────────────────────────
|
||||||
|
step "Reverting default shell to bash"
|
||||||
|
BASH_PATH=$(command -v bash 2>/dev/null || echo "/bin/bash")
|
||||||
|
CURRENT_SHELL=$(getent passwd "$USER" | cut -d: -f7)
|
||||||
|
if [[ "$CURRENT_SHELL" == *zsh* ]]; then
|
||||||
|
grep -qxF "$BASH_PATH" /etc/shells || echo "$BASH_PATH" | sudo tee -a /etc/shells
|
||||||
|
if chsh -s "$BASH_PATH" 2>/dev/null; then
|
||||||
|
success "Default shell reverted to $BASH_PATH"
|
||||||
|
else
|
||||||
|
warn "Could not change shell automatically — run: chsh -s $BASH_PATH"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
skip "Shell was not zsh ($CURRENT_SHELL)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 2. Remove Oh My Zsh ──────────────────────────────────────────────────
|
||||||
|
step "Removing Oh My Zsh"
|
||||||
|
if [[ -d "$HOME/.oh-my-zsh" ]]; then
|
||||||
|
rm -rf "$HOME/.oh-my-zsh"
|
||||||
|
success "Oh My Zsh removed"
|
||||||
|
else
|
||||||
|
skip "~/.oh-my-zsh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 3. Remove Powerlevel10k (standalone clone, if outside OMZ) ───────────
|
||||||
|
step "Removing Powerlevel10k"
|
||||||
|
for p10k_path in \
|
||||||
|
"$HOME/.oh-my-zsh/custom/themes/powerlevel10k" \
|
||||||
|
"$HOME/powerlevel10k" \
|
||||||
|
"${ZSH_CUSTOM:-}/themes/powerlevel10k"; do
|
||||||
|
if [[ -d "$p10k_path" ]]; then
|
||||||
|
rm -rf "$p10k_path"
|
||||||
|
success "Removed $p10k_path"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# ── 4. Remove Zsh plugin dirs ─────────────────────────────────────────────
|
||||||
|
step "Removing Zsh plugins"
|
||||||
|
for plugin in zsh-autosuggestions zsh-syntax-highlighting zsh-completions; do
|
||||||
|
PLUGIN_DIR="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/$plugin"
|
||||||
|
if [[ -d "$PLUGIN_DIR" ]]; then
|
||||||
|
rm -rf "$PLUGIN_DIR"
|
||||||
|
success "Removed plugin: $plugin"
|
||||||
|
else
|
||||||
|
skip "Plugin $plugin"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# ── 5. Remove colorls gem ─────────────────────────────────────────────────
|
||||||
|
step "Removing colorls Ruby gem"
|
||||||
|
if gem list -i colorls >/dev/null 2>&1; then
|
||||||
|
gem uninstall colorls -a -x 2>/dev/null && success "colorls removed" \
|
||||||
|
|| warn "colorls uninstall had warnings"
|
||||||
|
else
|
||||||
|
skip "colorls gem"
|
||||||
|
fi
|
||||||
|
# Clean up gem home if empty
|
||||||
|
GEM_HOME_DIR="$HOME/.gem"
|
||||||
|
if [[ -d "$GEM_HOME_DIR" ]]; then
|
||||||
|
REMAINING=$(find "$GEM_HOME_DIR" -name "*.gemspec" 2>/dev/null | wc -l)
|
||||||
|
if [[ "$REMAINING" -eq 0 ]]; then
|
||||||
|
rm -rf "$GEM_HOME_DIR"
|
||||||
|
success "Removed empty ~/.gem"
|
||||||
|
else
|
||||||
|
info "$REMAINING other gems remain in ~/.gem — leaving it"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 6. Remove fastfetch ───────────────────────────────────────────────────
|
||||||
|
step "Removing fastfetch"
|
||||||
|
if command -v fastfetch >/dev/null 2>&1; then
|
||||||
|
FF_PATH=$(command -v fastfetch)
|
||||||
|
# If installed via package manager
|
||||||
|
removed=false
|
||||||
|
case "$PM" in
|
||||||
|
pacman) sudo pacman -Rns --noconfirm fastfetch 2>/dev/null && removed=true ;;
|
||||||
|
apt) sudo apt remove -y --purge fastfetch 2>/dev/null && removed=true ;;
|
||||||
|
dnf) sudo dnf remove -y fastfetch 2>/dev/null && removed=true ;;
|
||||||
|
zypper) sudo zypper remove -y fastfetch 2>/dev/null && removed=true ;;
|
||||||
|
apk) sudo apk del fastfetch 2>/dev/null && removed=true ;;
|
||||||
|
esac
|
||||||
|
# If it was a manually installed binary
|
||||||
|
if [[ "$removed" == false ]] || command -v fastfetch >/dev/null 2>&1; then
|
||||||
|
sudo rm -f /usr/local/bin/fastfetch /usr/bin/fastfetch 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
command -v fastfetch >/dev/null 2>&1 \
|
||||||
|
&& warn "fastfetch still found at $(command -v fastfetch) — remove manually" \
|
||||||
|
|| success "fastfetch removed"
|
||||||
|
else
|
||||||
|
skip "fastfetch"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 7. Remove Zsh itself ──────────────────────────────────────────────────
|
||||||
|
step "Removing Zsh"
|
||||||
|
if command -v zsh >/dev/null 2>&1; then
|
||||||
|
printf " Remove zsh package itself? (leaves system zsh on some distros) [y/N]: "
|
||||||
|
read -r yn
|
||||||
|
if [[ "${yn,,}" == "y" ]]; then
|
||||||
|
pkg_remove zsh
|
||||||
|
command -v zsh >/dev/null 2>&1 \
|
||||||
|
&& warn "zsh still present (may be a system dependency)" \
|
||||||
|
|| success "zsh removed"
|
||||||
|
else
|
||||||
|
info "Zsh package kept (shell reverted to bash above)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
skip "zsh (not installed)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 8. Remove dot files ───────────────────────────────────────────────────
|
||||||
|
step "Removing ~/.zshrc and ~/.p10k.zsh"
|
||||||
|
for f in "$HOME/.zshrc" "$HOME/.p10k.zsh" "$HOME/.zsh_history"; do
|
||||||
|
if [[ -f "$f" ]]; then
|
||||||
|
# Back up before deleting
|
||||||
|
cp "$f" "${f}.uninstall-backup-$(date +%Y%m%d)" 2>/dev/null || true
|
||||||
|
rm -f "$f"
|
||||||
|
success "Removed $f (backup saved as ${f}.uninstall-backup-*)"
|
||||||
|
else
|
||||||
|
skip "$f"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# ── 9. Remove Hack Nerd Font ──────────────────────────────────────────────
|
||||||
|
step "Removing Hack Nerd Font"
|
||||||
|
FONT_DIR="/usr/local/share/fonts/nerd-fonts"
|
||||||
|
if [[ -d "$FONT_DIR" ]]; then
|
||||||
|
sudo rm -rf "$FONT_DIR"
|
||||||
|
sudo fc-cache -f 2>/dev/null || true
|
||||||
|
success "Hack Nerd Font removed from $FONT_DIR"
|
||||||
|
else
|
||||||
|
skip "$FONT_DIR"
|
||||||
|
fi
|
||||||
|
# Also check user font dir
|
||||||
|
USER_FONT_DIR="$HOME/.local/share/fonts/nerd-fonts"
|
||||||
|
if [[ -d "$USER_FONT_DIR" ]]; then
|
||||||
|
rm -rf "$USER_FONT_DIR"
|
||||||
|
fc-cache -f "$HOME/.local/share/fonts" 2>/dev/null || true
|
||||||
|
success "Removed user font dir $USER_FONT_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 10. Remove fontconfig override ───────────────────────────────────────
|
||||||
|
step "Removing fontconfig monospace alias"
|
||||||
|
if [[ -f /etc/fonts/local.conf ]]; then
|
||||||
|
if grep -q "Hack Nerd Font" /etc/fonts/local.conf 2>/dev/null; then
|
||||||
|
sudo rm -f /etc/fonts/local.conf
|
||||||
|
sudo fc-cache -f 2>/dev/null || true
|
||||||
|
success "Removed /etc/fonts/local.conf"
|
||||||
|
else
|
||||||
|
info "/etc/fonts/local.conf exists but doesn't contain Hack Nerd Font — leaving it"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
skip "/etc/fonts/local.conf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 11. Clean up PATH entries added to shell rc files ────────────────────
|
||||||
|
step "Cleaning gem PATH entries from shell rc files"
|
||||||
|
for rc in "$HOME/.bashrc" "$HOME/.zshrc" "$HOME/.bash_profile" "$HOME/.profile"; do
|
||||||
|
if [[ -f "$rc" ]]; then
|
||||||
|
if grep -q "\.gem" "$rc" 2>/dev/null; then
|
||||||
|
sed -i '/\.gem\/ruby/d' "$rc" 2>/dev/null || true
|
||||||
|
sed -i '/GEM_HOME/d' "$rc" 2>/dev/null || true
|
||||||
|
success "Cleaned gem PATH from $rc"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# B — UNINSTALL PORTAINER + DOCKER
|
||||||
|
# =============================================================================
|
||||||
|
uninstall_docker_portainer() {
|
||||||
|
|
||||||
|
# ── 1. Stop and remove Portainer ─────────────────────────────────────────
|
||||||
|
step "Removing Portainer CE"
|
||||||
|
if command -v docker >/dev/null 2>&1; then
|
||||||
|
DOCKER_CMD="docker"
|
||||||
|
docker info >/dev/null 2>&1 || DOCKER_CMD="sudo docker"
|
||||||
|
|
||||||
|
if $DOCKER_CMD ps -a --format '{{.Names}}' 2>/dev/null | grep -q "^portainer$"; then
|
||||||
|
$DOCKER_CMD stop portainer 2>/dev/null || true
|
||||||
|
$DOCKER_CMD rm portainer 2>/dev/null || true
|
||||||
|
success "Portainer container stopped and removed"
|
||||||
|
else
|
||||||
|
skip "Portainer container"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove portainer data volume
|
||||||
|
if $DOCKER_CMD volume ls --format '{{.Name}}' 2>/dev/null | grep -q "^portainer_data$"; then
|
||||||
|
printf " Remove portainer_data volume? This deletes all Portainer settings [y/N]: "
|
||||||
|
read -r yn
|
||||||
|
if [[ "${yn,,}" == "y" ]]; then
|
||||||
|
$DOCKER_CMD volume rm portainer_data 2>/dev/null || true
|
||||||
|
success "portainer_data volume removed"
|
||||||
|
else
|
||||||
|
info "portainer_data volume kept"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
skip "portainer_data volume"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove the image
|
||||||
|
if $DOCKER_CMD image ls --format '{{.Repository}}:{{.Tag}}' 2>/dev/null | grep -q "portainer/portainer-ce"; then
|
||||||
|
printf " Remove Portainer CE docker image? [y/N]: "
|
||||||
|
read -r yn
|
||||||
|
if [[ "${yn,,}" == "y" ]]; then
|
||||||
|
$DOCKER_CMD rmi portainer/portainer-ce:latest 2>/dev/null || true
|
||||||
|
success "Portainer CE image removed"
|
||||||
|
else
|
||||||
|
info "Portainer CE image kept"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
skip "Docker not installed — Portainer check skipped"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 2. Remove Docker ──────────────────────────────────────────────────────
|
||||||
|
step "Removing Docker"
|
||||||
|
if command -v docker >/dev/null 2>&1; then
|
||||||
|
printf " ${BOLD}${RED}Remove Docker CE completely?${RESET} This removes ALL containers, images and volumes [y/N]: "
|
||||||
|
read -r yn
|
||||||
|
if [[ "${yn,,}" != "y" ]]; then
|
||||||
|
info "Docker kept — only Portainer was removed"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Stop daemon first
|
||||||
|
sudo systemctl stop docker docker.socket 2>/dev/null || sudo service docker stop 2>/dev/null || true
|
||||||
|
sudo systemctl disable docker docker.socket 2>/dev/null || true
|
||||||
|
|
||||||
|
case "$PM" in
|
||||||
|
pacman)
|
||||||
|
sudo pacman -Rns --noconfirm docker docker-compose 2>/dev/null || true
|
||||||
|
;;
|
||||||
|
apt)
|
||||||
|
sudo apt remove -y --purge \
|
||||||
|
docker-ce docker-ce-cli containerd.io \
|
||||||
|
docker-buildx-plugin docker-compose-plugin \
|
||||||
|
docker-compose 2>/dev/null || true
|
||||||
|
sudo apt autoremove -y 2>/dev/null || true
|
||||||
|
# Remove Docker apt repo
|
||||||
|
sudo rm -f /etc/apt/sources.list.d/docker.list
|
||||||
|
sudo rm -f /etc/apt/keyrings/docker.gpg
|
||||||
|
sudo apt update -qq 2>/dev/null || true
|
||||||
|
;;
|
||||||
|
dnf)
|
||||||
|
sudo dnf remove -y \
|
||||||
|
docker-ce docker-ce-cli containerd.io \
|
||||||
|
docker-buildx-plugin docker-compose-plugin 2>/dev/null || true
|
||||||
|
sudo rm -f /etc/yum.repos.d/docker-ce.repo 2>/dev/null || true
|
||||||
|
;;
|
||||||
|
zypper)
|
||||||
|
sudo zypper remove -y docker docker-compose 2>/dev/null || true
|
||||||
|
;;
|
||||||
|
apk)
|
||||||
|
sudo apk del docker docker-compose 2>/dev/null || true
|
||||||
|
sudo rc-update del docker boot 2>/dev/null || true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Remove standalone docker-compose binary if present
|
||||||
|
[[ -f /usr/local/bin/docker-compose ]] && sudo rm -f /usr/local/bin/docker-compose \
|
||||||
|
&& success "Removed standalone docker-compose"
|
||||||
|
|
||||||
|
success "Docker CE removed"
|
||||||
|
else
|
||||||
|
skip "Docker (not installed)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 3. Remove Docker data directories ────────────────────────────────────
|
||||||
|
step "Removing Docker data directories"
|
||||||
|
for dir in /var/lib/docker /var/lib/containerd /etc/docker; do
|
||||||
|
if [[ -d "$dir" ]]; then
|
||||||
|
printf " Remove %s? [y/N]: " "$dir"
|
||||||
|
read -r yn
|
||||||
|
if [[ "${yn,,}" == "y" ]]; then
|
||||||
|
sudo rm -rf "$dir"
|
||||||
|
success "Removed $dir"
|
||||||
|
else
|
||||||
|
info "Kept $dir"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
skip "$dir"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove user docker config
|
||||||
|
if [[ -d "$HOME/.docker" ]]; then
|
||||||
|
rm -rf "$HOME/.docker"
|
||||||
|
success "Removed ~/.docker"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 4. Remove user from docker group ─────────────────────────────────────
|
||||||
|
step "Removing $USER from docker group"
|
||||||
|
if getent group docker >/dev/null 2>&1; then
|
||||||
|
if groups "$USER" | grep -qw docker; then
|
||||||
|
sudo gpasswd -d "$USER" docker 2>/dev/null \
|
||||||
|
&& success "$USER removed from docker group" \
|
||||||
|
|| warn "Could not remove $USER from docker group"
|
||||||
|
else
|
||||||
|
skip "$USER was not in docker group"
|
||||||
|
fi
|
||||||
|
printf " Delete the docker group itself? [y/N]: "
|
||||||
|
read -r yn
|
||||||
|
if [[ "${yn,,}" == "y" ]]; then
|
||||||
|
sudo groupdel docker 2>/dev/null && success "docker group deleted" \
|
||||||
|
|| warn "Could not delete docker group"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
skip "docker group (does not exist)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 5. Remove Docker socket and service files (if any remain) ────────────
|
||||||
|
step "Cleaning up Docker service files"
|
||||||
|
for f in \
|
||||||
|
/lib/systemd/system/docker.service \
|
||||||
|
/lib/systemd/system/docker.socket \
|
||||||
|
/etc/systemd/system/docker.service \
|
||||||
|
/etc/systemd/system/docker.socket; do
|
||||||
|
if [[ -f "$f" ]]; then
|
||||||
|
sudo rm -f "$f"
|
||||||
|
success "Removed $f"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
sudo systemctl daemon-reload 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# RUN SELECTED SECTIONS
|
||||||
|
# =============================================================================
|
||||||
|
[[ "$DO_ZSH" == true ]] && uninstall_zsh_font
|
||||||
|
[[ "$DO_DOCKER" == true ]] && uninstall_docker_portainer
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# DONE
|
||||||
|
# =============================================================================
|
||||||
|
echo ""
|
||||||
|
echo -e "${LINE}"
|
||||||
|
echo -e "${BOLD}${GREEN} ✅ Uninstall complete!${RESET}"
|
||||||
|
echo -e "${LINE}"
|
||||||
|
[[ "$DO_ZSH" == true ]] && echo -e " ${CYAN}Zsh/Font:${RESET} removed — default shell reverted to bash"
|
||||||
|
[[ "$DO_DOCKER" == true ]] && echo -e " ${CYAN}Docker:${RESET} removed — log out and back in to clear group session"
|
||||||
|
echo -e " ${YELLOW}Log:${RESET} $LOG_FILE"
|
||||||
|
echo -e "${LINE}"
|
||||||
|
echo ""
|
||||||
|
if [[ "$DO_ZSH" == true ]]; then
|
||||||
|
echo -e " ${YELLOW}Note:${RESET} Log out and back in for shell change to take full effect."
|
||||||
|
fi
|
||||||
|
if [[ "$DO_DOCKER" == true ]]; then
|
||||||
|
echo -e " ${YELLOW}Note:${RESET} Log out and back in to clear docker group from your session."
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
94
uninstall_zsh_setup.sh
Normal file
94
uninstall_zsh_setup.sh
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e # Exit immediately if a command exits with a non-zero status
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BOLD='\033[1m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
info() { echo -e "${YELLOW}ℹ️ $*${NC}"; }
|
||||||
|
success() { echo -e "${GREEN}✅ $*${NC}"; }
|
||||||
|
warn() { echo -e "${YELLOW}⚠️ $*${NC}"; }
|
||||||
|
error() { echo -e "${RED}❌ $*${NC}"; }
|
||||||
|
step() { echo -e "${BOLD}${YELLOW}--- $* ---${NC}"; }
|
||||||
|
|
||||||
|
step "Uninstalling Zsh/Powerlevel10k setup and related tools"
|
||||||
|
|
||||||
|
# 1. Remove Oh My Zsh directory
|
||||||
|
info "Removing Oh My Zsh directory..."
|
||||||
|
if [ -d "$HOME/.oh-my-zsh" ]; then
|
||||||
|
rm -rf "$HOME/.oh-my-zsh"
|
||||||
|
success "Oh My Zsh directory removed."
|
||||||
|
else
|
||||||
|
warn "Oh My Zsh directory not found."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. Remove Zsh configuration files
|
||||||
|
info "Removing Zsh configuration files..."
|
||||||
|
ZSH_CONFIG_FILES=("$HOME/.zshrc" "$HOME/.zshenv" "$HOME/.zprofile" "$HOME/.zlogin" "$HOME/.p10k.zsh")
|
||||||
|
for file in "${ZSH_CONFIG_FILES[@]}"; do
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
rm -f "$file"
|
||||||
|
success "Removed $file"
|
||||||
|
else
|
||||||
|
warn "$file not found."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 3. Remove up.sh maintenance script
|
||||||
|
info "Removing up.sh maintenance script..."
|
||||||
|
if [ -f "$HOME/Documents/up.sh" ]; then
|
||||||
|
rm -f "$HOME/Documents/up.sh"
|
||||||
|
success "up.sh maintenance script removed."
|
||||||
|
else
|
||||||
|
warn "up.sh maintenance script not found."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4. Uninstall colorls (user gem)
|
||||||
|
info "Uninstalling colorls Ruby gem..."
|
||||||
|
# Ensure GEM_HOME and PATH are set correctly for user gems
|
||||||
|
export GEM_HOME="$HOME/.gem"
|
||||||
|
export PATH="$PATH:$GEM_HOME/bin"
|
||||||
|
if gem list -i colorls >/dev/null 2>&1; then
|
||||||
|
if gem uninstall colorls; then # Removed -x and sudo
|
||||||
|
success "colorls uninstalled."
|
||||||
|
else
|
||||||
|
error "Failed to uninstall colorls."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "colorls gem not found."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 5. Uninstall fastfetch
|
||||||
|
info "Uninstalling fastfetch..."
|
||||||
|
if command -v fastfetch >/dev/null 2>&1; then
|
||||||
|
# Assume it was installed via the curl installer which puts files in /usr/local
|
||||||
|
if sudo rm -f /usr/local/bin/fastfetch && sudo rm -rf /usr/local/share/fastfetch; then
|
||||||
|
success "fastfetch uninstalled."
|
||||||
|
else
|
||||||
|
error "Failed to remove fastfetch binaries. Manual removal may be needed."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "fastfetch not found."
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# 6. Optionally restore default shell to bash
|
||||||
|
# Check if zsh is the current default shell before attempting to change
|
||||||
|
CURRENT_DEFAULT_SHELL=$(getent passwd "$USER" | awk -F: '{print $NF}')
|
||||||
|
if [ "$CURRENT_DEFAULT_SHELL" != "/bin/bash" ] && [ -f "/bin/bash" ]; then
|
||||||
|
info "Restoring default shell to /bin/bash..."
|
||||||
|
if chsh -s /bin/bash "$USER"; then # Specify user for chsh
|
||||||
|
success "Default shell changed to /bin/bash."
|
||||||
|
echo -e "${GREEN}Please log out and log in again for shell changes to take effect.${NC}"
|
||||||
|
else
|
||||||
|
error "Failed to change default shell to /bin/bash. You may need to do it manually."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
success "Default shell is already /bin/bash or /bin/bash not found."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${BOLD}${GREEN}✅ Uninstallation complete.${NC}"
|
||||||
|
echo -e "${BOLD}${GREEN}Note: Log out and log back in for shell changes to fully apply.${NC}"
|
||||||
186
update_zshrc.sh
Normal file
186
update_zshrc.sh
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# 🔧 StianNOR-ZSHkit — .zshrc Merge Script
|
||||||
|
# Merges managed sections from ZSHkit/.zshrc into the live ~/.zshrc
|
||||||
|
# without overwriting personal aliases or custom configuration.
|
||||||
|
#
|
||||||
|
# How it works:
|
||||||
|
# - Managed sections in ~/.zshrc are wrapped with markers:
|
||||||
|
# # --- ZSHKIT:section_name ---
|
||||||
|
# ... content ...
|
||||||
|
# # --- /ZSHKIT:section_name ---
|
||||||
|
# - On first run, markers are injected into your existing ~/.zshrc
|
||||||
|
# - On subsequent runs, content between markers is updated from ZSHkit
|
||||||
|
# - Everything outside the markers is never touched
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./update_zshrc.sh — merge and apply
|
||||||
|
# ./update_zshrc.sh --dry-run — show what would change, no writes
|
||||||
|
# ./update_zshrc.sh --status — show which sections are present
|
||||||
|
# =============================================================================
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'
|
||||||
|
RED='\033[0;31m'; BOLD='\033[1m'; RESET='\033[0m'
|
||||||
|
LINE="────────────────────────────────────────────────────────────────────────────"
|
||||||
|
|
||||||
|
info() { echo -e "${CYAN}ℹ $*${RESET}"; }
|
||||||
|
success() { echo -e "${GREEN}✅ $*${RESET}"; }
|
||||||
|
warn() { echo -e "${YELLOW}⚠ $*${RESET}"; }
|
||||||
|
error() { echo -e "${RED}❌ $*${RESET}"; }
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
SOURCE="$SCRIPT_DIR/.zshrc"
|
||||||
|
TARGET="$HOME/.zshrc"
|
||||||
|
BACKUP="$HOME/.zshrc.bak.$(date +%Y%m%d-%H%M%S)"
|
||||||
|
DRY_RUN=false
|
||||||
|
STATUS_ONLY=false
|
||||||
|
|
||||||
|
case "${1:-}" in
|
||||||
|
--dry-run) DRY_RUN=true ;;
|
||||||
|
--status) STATUS_ONLY=true ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ ! -f "$SOURCE" ]]; then
|
||||||
|
error "Source not found: $SOURCE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$TARGET" ]]; then
|
||||||
|
warn "No ~/.zshrc found — copying source directly"
|
||||||
|
cp "$SOURCE" "$TARGET"
|
||||||
|
success "Created $TARGET from ZSHkit source"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
declare -A SECTION_START=(
|
||||||
|
[autosuggestions]="# ─── Autosuggestions"
|
||||||
|
[aliases]="# ─── User Aliases and Functions"
|
||||||
|
)
|
||||||
|
declare -A SECTION_END=(
|
||||||
|
[autosuggestions]="source \$ZSH/oh-my-zsh.sh"
|
||||||
|
[aliases]="alias rsy="
|
||||||
|
)
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# STATUS MODE
|
||||||
|
# =============================================================================
|
||||||
|
if [[ "$STATUS_ONLY" = true ]]; then
|
||||||
|
echo -e "\n${BOLD}${CYAN}🔧 .zshrc Managed Sections Status${RESET}"
|
||||||
|
echo -e "${LINE}"
|
||||||
|
for section in "${!SECTION_START[@]}"; do
|
||||||
|
marker="# --- ZSHKIT:${section} ---"
|
||||||
|
if grep -qF "$marker" "$TARGET" 2>/dev/null; then
|
||||||
|
success "Section present: $section"
|
||||||
|
else
|
||||||
|
warn "Section missing (will be injected on next run): $section"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo -e "${LINE}\n"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# BACKUP
|
||||||
|
# =============================================================================
|
||||||
|
cp "$TARGET" "$BACKUP"
|
||||||
|
info "Backup saved: $BACKUP"
|
||||||
|
|
||||||
|
echo -e "\n${BOLD}${CYAN}🔧 Merging .zshrc sections${RESET}"
|
||||||
|
echo -e "${LINE}"
|
||||||
|
|
||||||
|
CHANGED=0
|
||||||
|
|
||||||
|
merge_section() {
|
||||||
|
local name="$1"
|
||||||
|
local start_pat="$2"
|
||||||
|
local end_pat="$3"
|
||||||
|
|
||||||
|
local begin_marker="# --- ZSHKIT:${name} ---"
|
||||||
|
local end_marker="# --- /ZSHKIT:${name} ---"
|
||||||
|
|
||||||
|
local new_content
|
||||||
|
new_content=$(awk "/$start_pat/{found=1} found{print} /$end_pat/{if(found) {found=0}}" "$SOURCE")
|
||||||
|
|
||||||
|
if [[ -z "$new_content" ]]; then
|
||||||
|
warn "Could not extract section '$name' from source — skipping"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local block
|
||||||
|
block="$begin_marker
|
||||||
|
$new_content
|
||||||
|
$end_marker"
|
||||||
|
|
||||||
|
if grep -qF "$begin_marker" "$TARGET"; then
|
||||||
|
local existing
|
||||||
|
existing=$(awk "/$begin_marker/{found=1; next} /$end_marker/{found=0; next} found{print}" "$TARGET")
|
||||||
|
if [[ "$existing" == "$new_content" ]]; then
|
||||||
|
success "Up to date: $name"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [[ "$DRY_RUN" = true ]]; then
|
||||||
|
warn "[DRY RUN] Would update section: $name"
|
||||||
|
diff <(echo "$existing") <(echo "$new_content") || true
|
||||||
|
else
|
||||||
|
python3 - "$TARGET" "$begin_marker" "$end_marker" "$new_content" <<'PYEOF'
|
||||||
|
import sys, re
|
||||||
|
target = sys.argv[1]
|
||||||
|
begin = sys.argv[2]
|
||||||
|
end = sys.argv[3]
|
||||||
|
new_body = sys.argv[4]
|
||||||
|
with open(target, 'r') as f:
|
||||||
|
content = f.read()
|
||||||
|
pattern = re.escape(begin) + r'.*?' + re.escape(end)
|
||||||
|
replacement = begin + '\n' + new_body + '\n' + end
|
||||||
|
new_content = re.sub(pattern, replacement, content, flags=re.DOTALL)
|
||||||
|
with open(target, 'w') as f:
|
||||||
|
f.write(new_content)
|
||||||
|
PYEOF
|
||||||
|
success "Updated section: $name"
|
||||||
|
(( CHANGED++ )) || true
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [[ "$DRY_RUN" = true ]]; then
|
||||||
|
warn "[DRY RUN] Would inject new section: $name"
|
||||||
|
else
|
||||||
|
if grep -q "# End of .zshrc" "$TARGET"; then
|
||||||
|
python3 - "$TARGET" "# End of .zshrc" "$block" <<'PYEOF'
|
||||||
|
import sys
|
||||||
|
target = sys.argv[1]
|
||||||
|
marker = sys.argv[2]
|
||||||
|
new_block = sys.argv[3]
|
||||||
|
with open(target, 'r') as f:
|
||||||
|
content = f.read()
|
||||||
|
content = content.replace(marker, new_block + '\n\n' + marker)
|
||||||
|
with open(target, 'w') as f:
|
||||||
|
f.write(content)
|
||||||
|
PYEOF
|
||||||
|
else
|
||||||
|
echo "" >> "$TARGET"
|
||||||
|
echo "$block" >> "$TARGET"
|
||||||
|
fi
|
||||||
|
success "Injected new section: $name"
|
||||||
|
(( CHANGED++ )) || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
merge_section "autosuggestions" \
|
||||||
|
"# ─── Autosuggestions" \
|
||||||
|
"source \\\$ZSH/oh-my-zsh.sh"
|
||||||
|
|
||||||
|
merge_section "aliases" \
|
||||||
|
"# ─── User Aliases and Functions" \
|
||||||
|
"alias rsy="
|
||||||
|
|
||||||
|
echo -e "${LINE}"
|
||||||
|
if [[ "$DRY_RUN" = true ]]; then
|
||||||
|
warn "Dry run complete — no files were modified"
|
||||||
|
elif [[ $CHANGED -eq 0 ]]; then
|
||||||
|
success "Everything already up to date — no changes needed"
|
||||||
|
else
|
||||||
|
success "$CHANGED section(s) updated in $TARGET"
|
||||||
|
echo -e "\n ${YELLOW}Run ${CYAN}fresh${RESET}${YELLOW} or open a new terminal to apply changes.${RESET}"
|
||||||
|
fi
|
||||||
|
echo -e "${LINE}\n"
|
||||||
Reference in New Issue
Block a user