Skip to content

Instantly share code, notes, and snippets.

@alexjoedt
Created December 15, 2025 15:16
Show Gist options
  • Select an option

  • Save alexjoedt/b785cf8dc236d24d79c7aaed3ff0ef10 to your computer and use it in GitHub Desktop.

Select an option

Save alexjoedt/b785cf8dc236d24d79c7aaed3ff0ef10 to your computer and use it in GitHub Desktop.
arch-nvidia-installer
#!/bin/bash
# This script is auto-generated with AI from https://github.com/JaKooLit/Arch-Hyprland
# Standalone NVIDIA Driver Installation Script for Arch Linux with Hyprland #
# This script installs and configures NVIDIA drivers for systems with Hyprland already installed #
set -e
#==============================================================================
# Color Definitions
#==============================================================================
OK="$(tput setaf 2)[OK]$(tput sgr0)"
ERROR="$(tput setaf 1)[ERROR]$(tput sgr0)"
NOTE="$(tput setaf 3)[NOTE]$(tput sgr0)"
INFO="$(tput setaf 4)[INFO]$(tput sgr0)"
WARN="$(tput setaf 1)[WARN]$(tput sgr0)"
CAT="$(tput setaf 6)[ACTION]$(tput sgr0)"
MAGENTA="$(tput setaf 5)"
YELLOW="$(tput setaf 3)"
GREEN="$(tput setaf 2)"
BLUE="$(tput setaf 4)"
SKY_BLUE="$(tput setaf 6)"
RESET="$(tput sgr0)"
#==============================================================================
# NVIDIA Packages to Install
#==============================================================================
nvidia_pkg=(
nvidia-dkms
nvidia-settings
nvidia-utils
libva
libva-nvidia-driver
)
#==============================================================================
# Script Setup
#==============================================================================
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR" || { echo "${ERROR} Failed to change directory to $SCRIPT_DIR"; exit 1; }
# Create Directory for Install Logs
if [ ! -d Install-Logs ]; then
mkdir -p Install-Logs
fi
# Set the name of the log file
LOG="Install-Logs/nvidia-install-$(date +%Y%m%d-%H%M%S).log"
#==============================================================================
# Helper Functions
#==============================================================================
# Show progress spinner during installation
show_progress() {
local pid=$1
local package_name=$2
local spin_chars=("●○○○○○○○○○" "○●○○○○○○○○" "○○●○○○○○○○" "○○○●○○○○○○" "○○○○●○○○○" \
"○○○○○●○○○○" "○○○○○○●○○○" "○○○○○○○●○○" "○○○○○○○○●○" "○○○○○○○○○●")
local i=0
tput civis
printf "\r${NOTE} Installing ${YELLOW}%s${RESET} ..." "$package_name"
while ps -p $pid &> /dev/null; do
printf "\r${NOTE} Installing ${YELLOW}%s${RESET} %s" "$package_name" "${spin_chars[i]}"
i=$(( (i + 1) % 10 ))
sleep 0.3
done
printf "\r${NOTE} Installing ${YELLOW}%s${RESET} ... Done!%-20s \n" "$package_name" ""
tput cnorm
}
# Detect AUR helper (yay or paru)
detect_aur_helper() {
if command -v yay &> /dev/null; then
ISAUR="yay"
elif command -v paru &> /dev/null; then
ISAUR="paru"
else
echo -e "${ERROR} No AUR helper found. Please install yay or paru first."
echo -e "${INFO} You can install yay with: git clone https://aur.archlinux.org/yay.git && cd yay && makepkg -si"
exit 1
fi
echo -e "${OK} Using ${YELLOW}$ISAUR${RESET} as AUR helper"
}
# Function to install packages
install_package() {
local pkg="$1"
local log_file="$2"
if $ISAUR -Q "$pkg" &>> /dev/null; then
echo -e "${INFO} ${MAGENTA}$pkg${RESET} is already installed. Skipping..."
else
(
stdbuf -oL $ISAUR -S --noconfirm "$pkg" 2>&1
) >> "$log_file" 2>&1 &
PID=$!
show_progress $PID "$pkg"
# Verify installation
if $ISAUR -Q "$pkg" &>> /dev/null; then
echo -e "${OK} Package ${YELLOW}$pkg${RESET} has been successfully installed!"
else
echo -e "\n${ERROR} ${YELLOW}$pkg${RESET} failed to install. Please check $log_file"
echo -e "${INFO} You may need to install this package manually."
fi
fi
}
# Print a section header
print_header() {
printf "\n"
echo -e "${SKY_BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
echo -e "${SKY_BLUE} $1${RESET}"
echo -e "${SKY_BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
printf "\n"
}
#==============================================================================
# Pre-flight Checks
#==============================================================================
clear
echo -e "${MAGENTA}"
cat << "EOF"
_ ___ _____ ____ ___ _
| \ | \ \ / /_ _| _ \_ _| / \
| \| |\ \ / / | || | | | | / _ \
| |\ | \ V / | || |_| | | / ___ \
|_| \_| \_/ |___|____/___/_/ \_\
___ _ _ _
|_ _|_ __ ___| |_ __ _| | | ___ _ __
| || '_ \/ __| __/ _` | | |/ _ \ '__|
| || | | \__ \ || (_| | | | __/ |
|___|_| |_|___/\__\__,_|_|_|\___|_|
EOF
echo -e "${RESET}"
echo -e "${INFO} Standalone NVIDIA Driver Installation for Arch Linux with Hyprland"
echo -e "${INFO} Log file: ${YELLOW}$LOG${RESET}"
printf "\n"
# Check if running as root
if [[ $EUID -eq 0 ]]; then
echo -e "${ERROR} This script should ${WARN}NOT${RESET} be executed as root!"
echo -e "${INFO} Please run as a regular user with sudo privileges."
exit 1
fi
# Check if this is Arch Linux
if [ ! -f /etc/arch-release ]; then
echo -e "${ERROR} This script is designed for Arch Linux only!"
exit 1
fi
# Check for NVIDIA GPU
print_header "Checking for NVIDIA GPU"
if ! lspci | grep -i nvidia &> /dev/null; then
echo -e "${ERROR} No NVIDIA GPU detected in your system!"
echo -e "${INFO} This script is only for systems with NVIDIA graphics cards."
exit 1
fi
echo -e "${OK} NVIDIA GPU detected:"
lspci | grep -i nvidia | tee -a "$LOG"
printf "\n"
# Check if Hyprland is installed
print_header "Checking Hyprland Installation"
if ! pacman -Qs hyprland > /dev/null; then
echo -e "${WARN} Hyprland is not installed on this system."
echo -e "${INFO} This script is designed for systems with Hyprland already installed."
read -p "Do you want to continue anyway? (y/N): " continue_choice
if [[ ! "$continue_choice" =~ ^[Yy]$ ]]; then
echo -e "${INFO} Exiting..."
exit 0
fi
else
echo -e "${OK} Hyprland is installed."
fi
# Detect AUR helper
print_header "Detecting AUR Helper"
detect_aur_helper
# Confirmation prompt
printf "\n"
echo -e "${CAT} This script will:"
echo -e " ${YELLOW}1.${RESET} Install NVIDIA drivers (nvidia-dkms) and utilities"
echo -e " ${YELLOW}2.${RESET} Install Linux kernel headers for your kernel(s)"
echo -e " ${YELLOW}3.${RESET} Configure mkinitcpio with NVIDIA modules"
echo -e " ${YELLOW}4.${RESET} Add modprobe options for NVIDIA"
echo -e " ${YELLOW}5.${RESET} Configure bootloader (GRUB or systemd-boot) if detected"
echo -e " ${YELLOW}6.${RESET} Rebuild initramfs"
printf "\n"
read -p "$(echo -e ${CAT}) Do you want to proceed? (y/N): " proceed
if [[ ! "$proceed" =~ ^[Yy]$ ]]; then
echo -e "${INFO} Installation cancelled."
exit 0
fi
#==============================================================================
# Remove Conflicting Hyprland Packages
#==============================================================================
print_header "Checking for Conflicting Packages"
echo -e "${YELLOW}Checking for conflicting hyprland-nvidia packages...${RESET}"
for hyprnvi in hyprland-git hyprland-nvidia hyprland-nvidia-git hyprland-nvidia-hidpi-git; do
if pacman -Qs "$hyprnvi" > /dev/null 2>&1; then
echo -e "${NOTE} Removing conflicting package: ${YELLOW}$hyprnvi${RESET}"
sudo pacman -R --noconfirm "$hyprnvi" 2>&1 | tee -a "$LOG" || true
fi
done
echo -e "${OK} Conflicting packages check complete."
#==============================================================================
# Install NVIDIA Packages and Kernel Headers
#==============================================================================
print_header "Installing NVIDIA Packages and Kernel Headers"
echo -e "${INFO} Detecting installed kernels..."
installed_kernels=$(cat /usr/lib/modules/*/pkgbase 2>/dev/null | sort -u)
if [ -z "$installed_kernels" ]; then
echo -e "${ERROR} Could not detect installed kernels!"
exit 1
fi
echo -e "${OK} Detected kernels: ${YELLOW}$installed_kernels${RESET}"
printf "\n"
# Install kernel headers and NVIDIA packages for each kernel
for krnl in $installed_kernels; do
echo -e "${INFO} Installing headers for kernel: ${YELLOW}$krnl${RESET}"
install_package "${krnl}-headers" "$LOG"
done
printf "\n"
echo -e "${INFO} Installing NVIDIA packages..."
for pkg in "${nvidia_pkg[@]}"; do
install_package "$pkg" "$LOG"
done
#==============================================================================
# Configure mkinitcpio
#==============================================================================
print_header "Configuring mkinitcpio"
MKINITCPIO_CONF="/etc/mkinitcpio.conf"
if grep -qE '^MODULES=.*nvidia. *nvidia_modeset.*nvidia_uvm.*nvidia_drm' "$MKINITCPIO_CONF"; then
echo -e "${INFO} NVIDIA modules already included in $MKINITCPIO_CONF" | tee -a "$LOG"
else
echo -e "${NOTE} Adding NVIDIA modules to $MKINITCPIO_CONF..."
sudo sed -Ei 's/^(MODULES=\([^\)]*)\)/\1 nvidia nvidia_modeset nvidia_uvm nvidia_drm)/' "$MKINITCPIO_CONF" 2>&1 | tee -a "$LOG"
echo -e "${OK} NVIDIA modules added to mkinitcpio.conf"
fi
#==============================================================================
# Rebuild Initramfs
#==============================================================================
print_header "Rebuilding Initramfs"
echo -e "${INFO} Rebuilding initramfs with mkinitcpio -P..."
sudo mkinitcpio -P 2>&1 | tee -a "$LOG"
echo -e "${OK} Initramfs rebuilt successfully."
#==============================================================================
# Configure modprobe
#==============================================================================
print_header "Configuring modprobe"
NVEA="/etc/modprobe.d/nvidia.conf"
if [ -f "$NVEA" ]; then
if grep -q "nvidia_drm modeset=1" "$NVEA" && grep -q "fbdev=1" "$NVEA"; then
echo -e "${INFO} ${YELLOW}nvidia_drm modeset=1 fbdev=1${RESET} already configured in $NVEA"
else
echo -e "${NOTE} Updating $NVEA with required options..."
echo "options nvidia_drm modeset=1 fbdev=1" | sudo tee "$NVEA" > /dev/null 2>&1 | tee -a "$LOG"
echo -e "${OK} modprobe options updated."
fi
else
echo -e "${NOTE} Creating $NVEA with NVIDIA options..."
echo "options nvidia_drm modeset=1 fbdev=1" | sudo tee "$NVEA" > /dev/null 2>&1 | tee -a "$LOG"
echo -e "${OK} Created $NVEA with modprobe options."
fi
#==============================================================================
# Configure GRUB (if present)
#==============================================================================
if [ -f /etc/default/grub ]; then
print_header "Configuring GRUB Bootloader"
echo -e "${INFO} ${YELLOW}GRUB${RESET} bootloader detected" | tee -a "$LOG"
GRUB_UPDATED=false
# Check and add nvidia-drm.modeset=1
if ! sudo grep -q "nvidia-drm.modeset=1" /etc/default/grub; then
sudo sed -i -e 's/\(GRUB_CMDLINE_LINUX_DEFAULT=".*\)"/\1 nvidia-drm.modeset=1"/' /etc/default/grub
echo -e "${OK} Added nvidia-drm.modeset=1 to GRUB config" | tee -a "$LOG"
GRUB_UPDATED=true
else
echo -e "${INFO} nvidia-drm.modeset=1 already present in GRUB config"
fi
# Check and add nvidia_drm.fbdev=1
if ! sudo grep -q "nvidia_drm.fbdev=1" /etc/default/grub; then
sudo sed -i -e 's/\(GRUB_CMDLINE_LINUX_DEFAULT=".*\)"/\1 nvidia_drm.fbdev=1"/' /etc/default/grub
echo -e "${OK} Added nvidia_drm.fbdev=1 to GRUB config" | tee -a "$LOG"
GRUB_UPDATED=true
else
echo -e "${INFO} nvidia_drm.fbdev=1 already present in GRUB config"
fi
# Regenerate GRUB config if changes were made
if [ "$GRUB_UPDATED" = true ]; then
echo -e "${NOTE} Regenerating GRUB configuration..."
sudo grub-mkconfig -o /boot/grub/grub.cfg 2>&1 | tee -a "$LOG"
echo -e "${OK} GRUB configuration regenerated"
fi
echo -e "${OK} GRUB bootloader configuration complete" | tee -a "$LOG"
fi
#==============================================================================
# Configure systemd-boot (if present)
#==============================================================================
if [ -f /boot/loader/loader.conf ]; then
print_header "Configuring systemd-boot Bootloader"
echo -e "${INFO} ${YELLOW}systemd-boot${RESET} bootloader detected" | tee -a "$LOG"
backup_count=$(find /boot/loader/entries/ -type f -name "*.conf.bak" 2>/dev/null | wc -l)
conf_count=$(find /boot/loader/entries/ -type f -name "*.conf" ! -name "*.bak" 2>/dev/null | wc -l)
if [ "$backup_count" -ne "$conf_count" ]; then
find /boot/loader/entries/ -type f -name "*.conf" ! -name "*.bak" | while read imgconf; do
# Create backup
sudo cp "$imgconf" "$imgconf.bak"
echo -e "${INFO} Backup created: ${YELLOW}$imgconf.bak${RESET}" | tee -a "$LOG"
# Clean up existing nvidia options and add new ones
sdopt=$(grep -w "^options" "$imgconf" | sed 's/\b nvidia-drm.modeset=[^ ]*\b//g' | sed 's/\b nvidia_drm.fbdev=[^ ]*\b//g')
sudo sed -i "/^options/c${sdopt} nvidia-drm.modeset=1 nvidia_drm.fbdev=1" "$imgconf" 2>&1 | tee -a "$LOG"
echo -e "${OK} Updated: ${YELLOW}$imgconf${RESET}"
done
echo -e "${OK} systemd-boot configuration complete" | tee -a "$LOG"
else
echo -e "${INFO} systemd-boot appears to be already configured (backups exist)" | tee -a "$LOG"
fi
fi
#==============================================================================
# Create NVIDIA Pacman Hook (Optional - Rebuilds initramfs on NVIDIA updates)
#==============================================================================
print_header "Creating NVIDIA Pacman Hook"
HOOK_DIR="/etc/pacman.d/hooks"
HOOK_FILE="$HOOK_DIR/nvidia.hook"
if [ ! -f "$HOOK_FILE" ]; then
echo -e "${NOTE} Creating pacman hook to rebuild initramfs on NVIDIA updates..."
sudo mkdir -p "$HOOK_DIR"
sudo tee "$HOOK_FILE" > /dev/null << 'HOOKEOF'
[Trigger]
Operation=Install
Operation=Upgrade
Operation=Remove
Type=Package
Target=nvidia
Target=nvidia-dkms
Target=nvidia-lts
Target=linux
Target=linux-lts
Target=linux-zen
Target=linux-hardened
[Action]
Description=Rebuilding initramfs after NVIDIA driver update...
Depends=mkinitcpio
When=PostTransaction
NeedsTargets
Exec=/bin/sh -c 'while read -r trg; do case $trg in linux*) exit 0; esac; done; /usr/bin/mkinitcpio -P'
HOOKEOF
echo -e "${OK} NVIDIA pacman hook created at $HOOK_FILE"
else
echo -e "${INFO} NVIDIA pacman hook already exists at $HOOK_FILE"
fi
#==============================================================================
# Summary and Final Steps
#==============================================================================
print_header "Installation Complete!"
echo -e "${OK} NVIDIA driver installation and configuration complete!"
printf "\n"
echo -e "${INFO} ${YELLOW}Summary of changes:${RESET}"
echo -e " ✓ Installed NVIDIA drivers and utilities"
echo -e " ✓ Configured mkinitcpio with NVIDIA modules"
echo -e " ✓ Created/updated modprobe configuration"
if [ -f /etc/default/grub ]; then
echo -e " ✓ Configured GRUB bootloader"
fi
if [ -f /boot/loader/loader.conf ]; then
echo -e " ✓ Configured systemd-boot bootloader"
fi
echo -e " ✓ Created pacman hook for automatic initramfs rebuild"
printf "\n"
echo -e "${WARN} ${YELLOW}IMPORTANT:${RESET} A system reboot is required to load the NVIDIA drivers!"
printf "\n"
read -p "$(echo -e ${CAT}) Would you like to reboot now? (y/N): " reboot_choice
if [[ "$reboot_choice" =~ ^[Yy]$ ]]; then
echo -e "${INFO} Rebooting system..."
sudo reboot
else
echo -e "${INFO} Please remember to reboot your system to apply the changes."
echo -e "${INFO} You can reboot manually with: ${YELLOW}sudo reboot${RESET}"
fi
printf "\n"
echo -e "${OK} Log file saved to: ${YELLOW}$LOG${RESET}"
echo -e "${INFO} Thank you for using the NVIDIA installer! 💫"
printf "\n"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment