#!/bin/bash # # CUPS 打印服务一键配置脚本 # 适用于 Armbian / Debian / Ubuntu # 作者: 自动生成 # 用法: # 安装: chmod +x setup_cups.sh && ./setup_cups.sh # 卸载: ./setup_cups.sh --uninstall # set -e # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 打印带颜色的信息 info() { echo -e "${BLUE}[信息]${NC} $1"; } success() { echo -e "${GREEN}[成功]${NC} $1"; } warn() { echo -e "${YELLOW}[警告]${NC} $1"; } error() { echo -e "${RED}[错误]${NC} $1"; exit 1; } # 检查是否为root用户 check_root() { if [ "$(id -u)" != "0" ]; then error "请使用 root 用户运行此脚本,或使用 sudo" fi } # 解决 apt 锁问题(停止自动更新服务) fix_apt_lock() { info "检查 apt 锁状态..." # 检查是否有 unattended-upgrades 进程 if pgrep -x "unattended-upgr" > /dev/null 2>&1; then warn "检测到自动更新服务正在运行,正在停止..." # 停止 unattended-upgrades 服务 systemctl stop unattended-upgrades 2>/dev/null || true # 等待进程结束(最多等待30秒) local count=0 while pgrep -x "unattended-upgr" > /dev/null 2>&1 && [ $count -lt 30 ]; do sleep 1 ((count++)) echo -ne "\r 等待自动更新进程结束... ${count}s" done echo "" # 如果还在运行,强制结束 if pgrep -x "unattended-upgr" > /dev/null 2>&1; then warn "强制结束自动更新进程..." killall unattended-upgr 2>/dev/null || true sleep 2 fi success "自动更新服务已停止" fi # 检查是否有其他 apt 进程 if fuser /var/lib/dpkg/lock-frontend > /dev/null 2>&1; then warn "检测到其他 apt 进程,等待其完成..." local count=0 while fuser /var/lib/dpkg/lock-frontend > /dev/null 2>&1 && [ $count -lt 60 ]; do sleep 1 ((count++)) echo -ne "\r 等待 apt 锁释放... ${count}s" done echo "" fi # 清理可能残留的锁文件 rm -f /var/lib/dpkg/lock-frontend 2>/dev/null || true rm -f /var/lib/dpkg/lock 2>/dev/null || true rm -f /var/cache/apt/archives/lock 2>/dev/null || true # 修复可能中断的安装 dpkg --configure -a 2>/dev/null || true success "apt 锁检查完成" } # 检测系统版本和架构 detect_os() { if [ -f /etc/os-release ]; then . /etc/os-release OS_ID=$ID OS_VERSION=$VERSION_CODENAME else OS_ID="unknown" OS_VERSION="unknown" fi # 检测CPU架构 ARCH=$(uname -m) case $ARCH in x86_64|amd64) ARCH_TYPE="amd64" ;; aarch64|arm64) ARCH_TYPE="arm64" ;; armv7l|armhf) ARCH_TYPE="armhf" ;; *) ARCH_TYPE="unknown" ;; esac } # 更换为国内源 change_to_china_mirror() { info "检测当前软件源..." detect_os # 检查源是否正确 local need_change=0 if [ "$OS_ID" = "ubuntu" ]; then if [ "$ARCH_TYPE" = "amd64" ]; then # x86_64 不应该用 ubuntu-ports if grep -q "ubuntu-ports" /etc/apt/sources.list 2>/dev/null; then warn "检测到错误的源配置 (ubuntu-ports 用于 ARM,当前是 x86_64)" need_change=1 elif grep -q "mirrors.tuna.tsinghua.edu.cn/ubuntu\|mirrors.aliyun.com/ubuntu\|mirrors.ustc.edu.cn/ubuntu" /etc/apt/sources.list 2>/dev/null; then success "当前已是正确的国内源,跳过换源" return 0 else need_change=1 fi else # ARM 应该用 ubuntu-ports if grep -q "mirrors.tuna.tsinghua.edu.cn/ubuntu-ports\|mirrors.aliyun.com/ubuntu-ports" /etc/apt/sources.list 2>/dev/null; then success "当前已是正确的国内源,跳过换源" return 0 else need_change=1 fi fi elif [ "$OS_ID" = "debian" ]; then if grep -q "mirrors.tuna.tsinghua.edu.cn/debian\|mirrors.aliyun.com/debian\|mirrors.ustc.edu.cn/debian" /etc/apt/sources.list 2>/dev/null; then success "当前已是正确的国内源,跳过换源" return 0 else need_change=1 fi else need_change=1 fi if [ "$need_change" = "0" ]; then return 0 fi # 备份原有源 if [ -f /etc/apt/sources.list ]; then cp /etc/apt/sources.list /etc/apt/sources.list.bak info "已备份原有源到 /etc/apt/sources.list.bak" fi # 根据系统类型选择源 case $OS_ID in debian) info "检测到 Debian 系统 ($OS_VERSION),更换为清华源..." cat > /etc/apt/sources.list << EOF # 清华大学 Debian 镜像源 deb https://mirrors.tuna.tsinghua.edu.cn/debian/ $OS_VERSION main contrib non-free non-free-firmware deb https://mirrors.tuna.tsinghua.edu.cn/debian/ $OS_VERSION-updates main contrib non-free non-free-firmware deb https://mirrors.tuna.tsinghua.edu.cn/debian/ $OS_VERSION-backports main contrib non-free non-free-firmware deb https://mirrors.tuna.tsinghua.edu.cn/debian-security $OS_VERSION-security main contrib non-free non-free-firmware EOF ;; ubuntu) # 根据架构选择正确的源 if [ "$ARCH_TYPE" = "amd64" ]; then UBUNTU_MIRROR="mirrors.tuna.tsinghua.edu.cn/ubuntu" info "检测到 Ubuntu 系统 ($OS_VERSION) [x86_64],更换为清华源..." else UBUNTU_MIRROR="mirrors.tuna.tsinghua.edu.cn/ubuntu-ports" info "检测到 Ubuntu 系统 ($OS_VERSION) [ARM],更换为清华源..." fi cat > /etc/apt/sources.list << EOF # 清华大学 Ubuntu 镜像源 deb https://$UBUNTU_MIRROR/ $OS_VERSION main restricted universe multiverse deb https://$UBUNTU_MIRROR/ $OS_VERSION-updates main restricted universe multiverse deb https://$UBUNTU_MIRROR/ $OS_VERSION-backports main restricted universe multiverse deb https://$UBUNTU_MIRROR/ $OS_VERSION-security main restricted universe multiverse EOF ;; *) warn "未识别的系统类型: $OS_ID,跳过换源" return 1 ;; esac # 处理 Armbian 源 if [ -f /etc/apt/sources.list.d/armbian.list ]; then if ! grep -q "mirrors.tuna.tsinghua.edu.cn" /etc/apt/sources.list.d/armbian.list; then cp /etc/apt/sources.list.d/armbian.list /etc/apt/sources.list.d/armbian.list.bak sed -i 's|apt.armbian.com|mirrors.tuna.tsinghua.edu.cn/armbian|g' /etc/apt/sources.list.d/armbian.list info "Armbian 源已更换为清华镜像" fi fi success "软件源已更换为国内镜像(清华大学)" } # 获取本机IP地址 get_ip() { ip addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' | head -n1 } # 获取默认网关 get_gateway() { ip route | grep default | awk '{print $3}' | head -n1 } # 获取主网络接口名称 get_interface() { ip route | grep default | awk '{print $5}' | head -n1 } # 获取子网掩码(CIDR格式) get_netmask() { local iface=$(get_interface) ip addr show "$iface" | grep -oP 'inet \K[\d.]+/\d+' | head -n1 | cut -d'/' -f2 } # 获取DNS服务器 get_dns() { # 尝试从 resolv.conf 获取 grep -E "^nameserver" /etc/resolv.conf 2>/dev/null | awk '{print $2}' | head -n2 | tr '\n' ' ' } # 配置静态IP configure_static_ip() { echo "" echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}" echo -e "${YELLOW} 配置静态 IP 地址 ${NC}" echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}" echo "" local current_ip=$(get_ip) local current_gateway=$(get_gateway) local current_interface=$(get_interface) local current_netmask=$(get_netmask) local current_dns=$(get_dns) echo -e "${BLUE}当前网络配置:${NC}" echo " 接口名称: $current_interface" echo " IP 地址: $current_ip" echo " 子网掩码: /$current_netmask" echo " 网关: $current_gateway" echo " DNS: $current_dns" echo "" # 询问是否使用当前IP echo -e "${YELLOW}是否将当前 IP ($current_ip) 设置为静态 IP?${NC}" echo " Y - 使用当前 IP" echo " N - 手动输入新 IP" echo "" read -p "选择 [Y/n]: " use_current < /dev/tty use_current=${use_current:-Y} local static_ip="" local static_gateway="" local static_netmask="" local static_dns="" if [[ "$use_current" =~ ^[Yy]$ ]]; then static_ip="$current_ip" static_gateway="$current_gateway" static_netmask="$current_netmask" static_dns="${current_dns:-8.8.8.8 114.114.114.114}" else echo "" read -p "请输入静态 IP 地址 (如 192.168.1.100): " static_ip < /dev/tty read -p "请输入子网掩码 (如 24,表示255.255.255.0): " static_netmask < /dev/tty read -p "请输入网关地址 (如 192.168.1.1): " static_gateway < /dev/tty read -p "请输入 DNS 服务器 (如 8.8.8.8 114.114.114.114): " static_dns < /dev/tty static_netmask=${static_netmask:-24} static_dns=${static_dns:-"8.8.8.8 114.114.114.114"} fi # 检查是否使用 NetworkManager if systemctl is-active --quiet NetworkManager 2>/dev/null; then configure_static_ip_networkmanager "$current_interface" "$static_ip" "$static_netmask" "$static_gateway" "$static_dns" # 检查是否使用 netplan (Ubuntu 18.04+) elif [ -d /etc/netplan ]; then configure_static_ip_netplan "$current_interface" "$static_ip" "$static_netmask" "$static_gateway" "$static_dns" # 使用传统的 /etc/network/interfaces else configure_static_ip_interfaces "$current_interface" "$static_ip" "$static_netmask" "$static_gateway" "$static_dns" fi } # 使用 NetworkManager 配置静态IP configure_static_ip_networkmanager() { local iface=$1 local ip=$2 local mask=$3 local gw=$4 local dns=$5 info "检测到 NetworkManager,使用 nmcli 配置..." # 获取连接名称 local conn_name=$(nmcli -t -f NAME,DEVICE con show --active | grep "$iface" | cut -d':' -f1) if [ -z "$conn_name" ]; then conn_name="$iface" fi # 配置静态IP nmcli con mod "$conn_name" ipv4.method manual nmcli con mod "$conn_name" ipv4.addresses "$ip/$mask" nmcli con mod "$conn_name" ipv4.gateway "$gw" nmcli con mod "$conn_name" ipv4.dns "$dns" # 重启连接 nmcli con down "$conn_name" 2>/dev/null || true nmcli con up "$conn_name" success "NetworkManager 静态 IP 配置完成" } # 使用 netplan 配置静态IP configure_static_ip_netplan() { local iface=$1 local ip=$2 local mask=$3 local gw=$4 local dns=$5 info "检测到 netplan,创建静态 IP 配置..." # 备份现有配置 for f in /etc/netplan/*.yaml; do if [ -f "$f" ]; then cp "$f" "$f.bak" info "已备份: $f -> $f.bak" fi done # 转换DNS格式 local dns_list="" for d in $dns; do dns_list="$dns_list, $d" done dns_list=$(echo "$dns_list" | sed 's/^, //') # 创建新的netplan配置 cat > /etc/netplan/01-static-ip.yaml << EOF # 静态 IP 配置 - 由 CUPS 一键脚本生成 network: version: 2 renderer: networkd ethernets: $iface: dhcp4: no addresses: - $ip/$mask routes: - to: default via: $gw nameservers: addresses: [$dns_list] EOF # 设置正确的权限(避免 "Permissions too open" 警告) chmod 600 /etc/netplan/01-static-ip.yaml # 删除其他可能冲突的配置 for f in /etc/netplan/*.yaml; do if [ "$f" != "/etc/netplan/01-static-ip.yaml" ] && [ -f "$f" ]; then rm -f "$f" info "移除冲突配置: $f" fi done # 应用配置 info "应用 netplan 配置..." netplan apply success "Netplan 静态 IP 配置完成" } # 使用传统 interfaces 文件配置静态IP configure_static_ip_interfaces() { local iface=$1 local ip=$2 local mask=$3 local gw=$4 local dns=$5 info "使用传统 /etc/network/interfaces 配置..." # 备份原配置 if [ -f /etc/network/interfaces ]; then cp /etc/network/interfaces /etc/network/interfaces.bak info "已备份: /etc/network/interfaces -> /etc/network/interfaces.bak" fi # 将CIDR转换为子网掩码 local netmask="" case $mask in 8) netmask="255.0.0.0" ;; 16) netmask="255.255.0.0" ;; 24) netmask="255.255.255.0" ;; 25) netmask="255.255.255.128" ;; 26) netmask="255.255.255.192" ;; 27) netmask="255.255.255.224" ;; 28) netmask="255.255.255.240" ;; 29) netmask="255.255.255.248" ;; 30) netmask="255.255.255.252" ;; *) netmask="255.255.255.0" ;; esac # 创建新配置 cat > /etc/network/interfaces << EOF # 静态 IP 配置 - 由 CUPS 一键脚本生成 # 备份文件: /etc/network/interfaces.bak # 本地回环接口 auto lo iface lo inet loopback # 主网络接口 - 静态IP auto $iface iface $iface inet static address $ip netmask $netmask gateway $gw dns-nameservers $dns EOF # 重启网络服务 info "重启网络服务..." systemctl restart networking 2>/dev/null || /etc/init.d/networking restart 2>/dev/null || true success "传统网络配置完成" } # 配置 DHCP 自动获取 IP configure_dhcp() { echo "" echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}" echo -e "${YELLOW} 切换为 DHCP 自动获取 IP ${NC}" echo -e "${YELLOW}═══════════════════════════════════════════════════════════${NC}" echo "" local current_ip=$(get_ip) local current_interface=$(get_interface) echo -e "${BLUE}当前网络配置:${NC}" echo " 接口名称: $current_interface" echo " 当前 IP: $current_ip" echo "" echo -e "${YELLOW}警告: 切换为 DHCP 后,IP 地址可能会改变!${NC}" echo " 请确保你能通过其他方式(如显示器/串口)访问设备" echo "" read -p "确定要切��为 DHCP 吗? [y/N]: " confirm < /dev/tty confirm=${confirm:-N} if [[ ! "$confirm" =~ ^[Yy]$ ]]; then echo "已取消" return 0 fi # 检查是否使用 NetworkManager if systemctl is-active --quiet NetworkManager 2>/dev/null; then configure_dhcp_networkmanager "$current_interface" # 检查是否使用 netplan (Ubuntu 18.04+) elif [ -d /etc/netplan ]; then configure_dhcp_netplan "$current_interface" # 使用传统的 /etc/network/interfaces else configure_dhcp_interfaces "$current_interface" fi show_dhcp_result } # 使用 NetworkManager 配置 DHCP configure_dhcp_networkmanager() { local iface=$1 info "检测到 NetworkManager,使用 nmcli 配置 DHCP..." # 获取连接名称 local conn_name=$(nmcli -t -f NAME,DEVICE con show --active | grep "$iface" | cut -d':' -f1) if [ -z "$conn_name" ]; then conn_name="$iface" fi # 配置 DHCP nmcli con mod "$conn_name" ipv4.method auto nmcli con mod "$conn_name" ipv4.addresses "" nmcli con mod "$conn_name" ipv4.gateway "" nmcli con mod "$conn_name" ipv4.dns "" # 重启连接 nmcli con down "$conn_name" 2>/dev/null || true nmcli con up "$conn_name" success "NetworkManager DHCP 配置完成" } # 使用 netplan 配置 DHCP configure_dhcp_netplan() { local iface=$1 info "检测到 netplan,创建 DHCP 配置..." # 备份现有配置 for f in /etc/netplan/*.yaml; do if [ -f "$f" ]; then cp "$f" "$f.bak" info "已备份: $f -> $f.bak" fi done # 创建新的 netplan DHCP 配置 cat > /etc/netplan/01-dhcp.yaml << EOF # DHCP 配置 - 由 CUPS 一键脚本生成 network: version: 2 renderer: networkd ethernets: $iface: dhcp4: yes EOF # 设置正确的权限 chmod 600 /etc/netplan/01-dhcp.yaml # 删除其他可能冲突的配置 for f in /etc/netplan/*.yaml; do if [ "$f" != "/etc/netplan/01-dhcp.yaml" ] && [ -f "$f" ]; then rm -f "$f" info "移除冲突配置: $f" fi done # 应用配置 info "应用 netplan 配置..." netplan apply success "Netplan DHCP 配置完成" } # 使用传统 interfaces 文件配置 DHCP configure_dhcp_interfaces() { local iface=$1 info "使用传统 /etc/network/interfaces 配置 DHCP..." # 备份原配置 if [ -f /etc/network/interfaces ]; then cp /etc/network/interfaces /etc/network/interfaces.bak info "已备份: /etc/network/interfaces -> /etc/network/interfaces.bak" fi # 创建新配置 cat > /etc/network/interfaces << EOF # DHCP 配置 - 由 CUPS 一键脚本生成 # 备份文件: /etc/network/interfaces.bak # 本地回环接口 auto lo iface lo inet loopback # 主网络接口 - DHCP auto $iface iface $iface inet dhcp EOF # 重启网络服务 info "重启网络服务..." systemctl restart networking 2>/dev/null || /etc/init.d/networking restart 2>/dev/null || true success "传统网络配置完成" } # 显示 DHCP 配置结果 show_dhcp_result() { # 等待网络重新配置 sleep 3 local new_ip=$(get_ip) local new_interface=$(get_interface) echo "" echo -e "${GREEN}╔══════════════════════════════════════════════════════════╗${NC}" echo -e "${GREEN}║ DHCP 配置完成! ║${NC}" echo -e "${GREEN}╚══════════════════════════════════════════════════════════╝${NC}" echo "" echo -e " ${BLUE}网络接口:${NC} $new_interface" echo -e " ${BLUE}当前 IP:${NC} $new_ip" echo "" echo -e " ${YELLOW}注意:${NC} IP 地址现在由 DHCP 服务器自动分配" echo -e " ${YELLOW} ${NC} 重启后 IP 可能会改变" echo "" } # 显示静态IP配置结果 show_static_ip_result() { local new_ip=$(get_ip) local new_gateway=$(get_gateway) local new_interface=$(get_interface) echo "" echo -e "${GREEN}╔══════════════════════════════════════════════════════════╗${NC}" echo -e "${GREEN}║ 静态 IP 配置完成! ║${NC}" echo -e "${GREEN}╚══════════════════════════════════════════════════════════╝${NC}" echo "" echo -e " ${BLUE}网络接口:${NC} $new_interface" echo -e " ${BLUE}静态 IP:${NC} $new_ip" echo -e " ${BLUE}网关:${NC} $new_gateway" echo "" echo -e " ${YELLOW}注意:${NC} IP 地址已固定,重启后不会改变" echo "" } # 显示欢迎信息 show_banner() { clear echo -e "${GREEN}" echo "╔══════════════════════════════════════════════════════════╗" echo "║ CUPS 打印服务一键配置脚本 ║" echo "║ 适用于 Armbian / Debian / Ubuntu ║" echo "╚══════════════════════════════════════════════════════════╝" echo -e "${NC}" echo "" } # 选择打印机驱动 select_drivers() { echo -e "${YELLOW}请选择要安装的打印机驱动 (可多选,用空格或逗号分隔):${NC}" echo "" echo " 1) 通用驱动 (推荐,支持大多数打印机)" echo " 2) HP 打印机 (hplip)" echo " 3) 爱普生 (gutenprint)" echo " 4) 兄弟 (brlaser)" echo " 5) 奔图 Pantum (从官网下载)" echo " 6) 全部安装 (不含奔图)" echo " 7) 虚拟 PDF 打印机 (测试连接用,无需真实打印机)" echo " 0) 仅安装CUPS (不安装额外驱动)" echo "" echo -e " ${BLUE}示例: 1 7 或 1,7 表示同时安装通用驱动和虚拟PDF打印机${NC}" echo "" read -p "请输入选项 (默认: 1 7): " driver_choice < /dev/tty driver_choice=${driver_choice:-"1 7"} # 统一分隔符 driver_choice=$(echo "$driver_choice" | tr ',' ' ') } # 安装奔图驱动 install_pantum_driver() { info "正在安装奔图 Pantum 打印机驱动..." # 检测系统架构 local arch=$(dpkg --print-architecture) info "检测到系统架构: $arch" # 奔图驱动下载地址 (通用Linux驱动) local pantum_url="" local pantum_file="" case $arch in arm64|aarch64) pantum_url="https://drivers.pantum.com/userfiles/files/download/drive/Pantum%20Ubuntu%20Driver%20V1_1_123_1.zip" ;; armhf|arm) pantum_url="https://drivers.pantum.com/userfiles/files/download/drive/Pantum%20Ubuntu%20Driver%20V1_1_123_1.zip" ;; amd64|x86_64) pantum_url="https://drivers.pantum.com/userfiles/files/download/drive/Pantum%20Ubuntu%20Driver%20V1_1_123_1.zip" ;; *) warn "不支持的架构: $arch,跳过奔图驱动安装" return 1 ;; esac # 创建临时目录 local tmp_dir=$(mktemp -d) cd "$tmp_dir" info "下载奔图驱动..." if ! wget -q --show-progress -O pantum_driver.zip "$pantum_url"; then warn "下载奔图驱动失败,尝试备用方案..." # 备用: 直接安装依赖,用户手动下载驱动 apt install -y libcups2 libcupsimage2 warn "请手动从 https://www.pantum.com 下载驱动并安装" cd - > /dev/null rm -rf "$tmp_dir" return 1 fi info "解压驱动包..." unzip -q pantum_driver.zip # 查找并安装deb包 local deb_file="" if [ "$arch" = "arm64" ] || [ "$arch" = "aarch64" ]; then deb_file=$(find . -name "*arm64*.deb" -o -name "*aarch64*.deb" 2>/dev/null | head -1) elif [ "$arch" = "armhf" ] || [ "$arch" = "arm" ]; then deb_file=$(find . -name "*armhf*.deb" -o -name "*arm*.deb" 2>/dev/null | grep -v arm64 | head -1) else deb_file=$(find . -name "*amd64*.deb" -o -name "*x86_64*.deb" 2>/dev/null | head -1) fi # 如果找不到对应架构,尝试通用包 if [ -z "$deb_file" ]; then deb_file=$(find . -name "*.deb" 2>/dev/null | head -1) fi if [ -n "$deb_file" ]; then info "安装驱动包: $deb_file" dpkg -i "$deb_file" || apt install -f -y success "奔图驱动安装完成" else warn "未找到适合的驱动包" warn "请手动从 https://www.pantum.com 下载驱动" fi # 清理 cd - > /dev/null rm -rf "$tmp_dir" } # 安装 HPLIP 插件(自动下载) install_hplip_plugin() { info "正在安装 HP 打印机插件..." # 检测 hplip 版本 local hplip_version="" if command -v hp-info > /dev/null 2>&1; then hplip_version=$(hp-info -v 2>/dev/null | grep -oP 'HPLIP \K[0-9.]+' | head -1) fi # 如果上面方法失败,尝试从包管理器获取 if [ -z "$hplip_version" ]; then hplip_version=$(dpkg -s hplip 2>/dev/null | grep "^Version:" | awk '{print $2}' | cut -d'-' -f1 | cut -d'+' -f1) fi if [ -z "$hplip_version" ]; then warn "无法检测 HPLIP 版本,跳过插件安装" return 1 fi info "检测到 HPLIP 版本: ${hplip_version}" # 插件文件路径 local plugin_file="/tmp/hplip-${hplip_version}-plugin.run" local plugin_url="http://www.openprinting.org/download/printdriver/auxfiles/HP/plugins/hplip-${hplip_version}-plugin.run" # 下载插件 info "下载 HP 插件: ${plugin_url}" if wget -q --show-progress -O "$plugin_file" "$plugin_url" 2>/dev/null; then success "插件下载完成" else warn "插件下载失败,尝试备用地址..." # 备用地址 plugin_url="https://developers.hp.com/sites/default/files/hplip-${hplip_version}-plugin.run" if wget -q --show-progress -O "$plugin_file" "$plugin_url" 2>/dev/null; then success "插件下载完成(备用地址)" else warn "插件下载失败" echo "" echo -e "${YELLOW}请手动下载安装 HP 插件:${NC}" echo -e " 下载: ${GREEN}http://www.openprinting.org/download/printdriver/auxfiles/HP/plugins/hplip-${hplip_version}-plugin.run${NC}" echo -e " 安装: ${GREEN}hp-plugin -i -p /tmp/hplip-${hplip_version}-plugin.run${NC}" echo "" return 1 fi fi # 安装插件(使用 expect 或直接执行) info "安装 HP 插件..." if command -v expect > /dev/null 2>&1; then # 使用 expect 自动应答 expect << EOF spawn sh "$plugin_file" --nox11 expect { "Do you accept" { send "y\r"; exp_continue } "Enter a directory path" { send "/usr/share/hplip/data/plugins\r"; exp_continue } eof } EOF else # 直接执行插件安装脚本 chmod +x "$plugin_file" sh "$plugin_file" --nox11 --keep --noexec --target /tmp/hplip-plugin-extract || true if [ -d /tmp/hplip-plugin-extract ]; then # 复制插件文件 mkdir -p /usr/share/hplip/data/plugins cp -f /tmp/hplip-plugin-extract/*.so /usr/share/hplip/data/plugins/ 2>/dev/null || true cp -f /tmp/hplip-plugin-extract/plugin.spec /usr/share/hplip/data/plugins/ 2>/dev/null || true # 设置权限 chmod 644 /usr/share/hplip/data/plugins/*.so 2>/dev/null || true chmod 644 /usr/share/hplip/data/plugins/plugin.spec 2>/dev/null || true # 创建版本标记 echo "[plugin]" > /var/lib/hp/hplip.state echo "installed = 1" >> /var/lib/hp/hplip.state echo "version = ${hplip_version}" >> /var/lib/hp/hplip.state mkdir -p /var/lib/hp rm -rf /tmp/hplip-plugin-extract success "HP 插件安装完成" else # 尝试使用 hp-plugin 命令 warn "尝试使用 hp-plugin 安装..." echo -e "\n${YELLOW}请在下面的提示中输入 y 接受许可协议${NC}\n" hp-plugin -i -p "$plugin_file" || { warn "自动安装失败" echo "" echo -e "${YELLOW}请手动安装 HP 插件:${NC}" echo -e " ${GREEN}hp-plugin -i -p ${plugin_file}${NC}" echo -e " 提示 GPG 验证失败时输入 ${GREEN}y${NC} 继续" echo "" } fi fi # 清理 rm -f "$plugin_file" 2>/dev/null || true # 保存版本号供后续使用 HPLIP_VERSION="$hplip_version" } # 安装驱动 install_drivers() { local packages="" local install_pantum=false local install_pdf=false local install_hp=false for choice in $driver_choice; do case $choice in 1) info "添加通用驱动..." packages="$packages printer-driver-all" ;; 2) info "添加 HP 驱动..." packages="$packages hplip" install_hp=true ;; 3) info "添加爱普生驱动..." packages="$packages printer-driver-gutenprint" ;; 4) info "添加兄弟驱动..." packages="$packages printer-driver-brlaser" ;; 5) install_pantum=true ;; 6) info "添加全部驱动..." packages="printer-driver-all hplip printer-driver-gutenprint printer-driver-brlaser" install_hp=true ;; 7) install_pdf=true ;; 0) info "跳过驱动安装" return 0 ;; esac done if [ -n "$packages" ]; then info "正在安装驱动: $packages" apt install -y $packages fi # 安装奔图驱动 if [ "$install_pantum" = true ]; then install_pantum_driver fi # 安装虚拟PDF打印机 if [ "$install_pdf" = true ]; then install_pdf_printer fi # 安装 HP 插件 if [ "$install_hp" = true ]; then install_hplip_plugin fi } # 安装中文界面模板 install_chinese_templates() { info "安装 CUPS 中文界面模板..." local templates_dir="/usr/share/cups/templates-zh_CN" # 先检查本地是否有模板目录 SCRIPT_DIR="$(cd "$(dirname "$0")" 2>/dev/null && pwd)" || SCRIPT_DIR="" if [ -n "$SCRIPT_DIR" ] && [ -d "$SCRIPT_DIR/cups-templates-zh_CN" ]; then # 本地有模板文件,直接复制 info "从本地复制中文模板..." mkdir -p "$templates_dir" cp -f "$SCRIPT_DIR/cups-templates-zh_CN/"*.tmpl "$templates_dir/" success "中文界面模板安装完成(本地)" else # 从 Gitee 下载模板(使用 zip 包方式,更可靠) info "从 Gitee 下载中文模板..." local tmp_dir=$(mktemp -d) local zip_url="https://gitee.com/yu-yon/S905L3A/repository/archive/master.zip" # 下载仓库 zip 包 if wget -q --show-progress -O "$tmp_dir/repo.zip" "$zip_url" 2>/dev/null || \ curl -sL -o "$tmp_dir/repo.zip" "$zip_url" 2>/dev/null; then # 解压 cd "$tmp_dir" unzip -q repo.zip 2>/dev/null # 查找模板目录 local extracted_dir=$(find . -type d -name "cups-templates-zh_CN" 2>/dev/null | head -1) if [ -n "$extracted_dir" ] && [ -d "$extracted_dir" ]; then mkdir -p "$templates_dir" cp -f "$extracted_dir"/*.tmpl "$templates_dir/" local count=$(ls "$templates_dir"/*.tmpl 2>/dev/null | wc -l) success "中文界面模板安装完成(已安装 $count 个文件)" else warn "解压后未找到模板目录" rm -rf "$tmp_dir" return 1 fi cd - > /dev/null rm -rf "$tmp_dir" else warn "中文模板下载失败,界面将显示英文" rm -rf "$tmp_dir" return 1 fi fi # 创建语言目录链接(兼容不同浏览器语言设置) ln -sf "$templates_dir" /usr/share/cups/templates-zh 2>/dev/null || true # 备份原英文模板并用中文覆盖默认模板(确保显示中文) if [ -d /usr/share/cups/templates ] && [ ! -d /usr/share/cups/templates-en-backup ]; then cp -r /usr/share/cups/templates /usr/share/cups/templates-en-backup info "已备份原英文模板到 templates-en-backup" fi cp -f "$templates_dir"/*.tmpl /usr/share/cups/templates/ success "中文模板已设为默认" # 自动适配CSS类名(兼容不同CUPS版本) # CUPS 2.4.7+ 使用 cups-header/cups-body/cups-footer # CUPS 2.4.1 及更早版本使用 header/body/footer local css_file="/usr/share/cups/doc-root/cups.css" if [ -f "$css_file" ]; then if grep -q "\.cups-header" "$css_file"; then info "检测到新版CUPS CSS类名,自动适配模板..." # 替换为新类名 sed -i 's/class="header"/class="cups-header"/g' "$templates_dir/header.tmpl" /usr/share/cups/templates/header.tmpl 2>/dev/null sed -i 's/class="body"/class="cups-body"/g' "$templates_dir/header.tmpl" /usr/share/cups/templates/header.tmpl 2>/dev/null sed -i 's/class="footer"/class="cups-footer"/g' "$templates_dir/trailer.tmpl" /usr/share/cups/templates/trailer.tmpl 2>/dev/null success "CSS类名已适配为新版格式" else info "检测到旧版CUPS CSS类名,模板兼容" fi fi } # 安装驱动管理器(Web界面安装驱动) install_driver_manager() { info "安装 CUPS 驱动管理器..." # 安装依赖 apt install -y python3 python3-pip python3-flask 2>/dev/null || { # 如果系统包不可用,使用 pip 安装 apt install -y python3 python3-pip pip3 install flask 2>/dev/null || pip3 install flask --break-system-packages 2>/dev/null } # 创建安装目录 local install_dir="/opt/cups-driver-manager" mkdir -p "$install_dir" # 复制文件 SCRIPT_DIR="$(cd "$(dirname "$0")" 2>/dev/null && pwd)" || SCRIPT_DIR="" if [ -n "$SCRIPT_DIR" ] && [ -f "$SCRIPT_DIR/cups-driver-manager/driver_manager.py" ]; then # 从本地复制 cp -f "$SCRIPT_DIR/cups-driver-manager/driver_manager.py" "$install_dir/" cp -f "$SCRIPT_DIR/cups-driver-manager/cups-driver-manager.service" /etc/systemd/system/ 2>/dev/null || true info "从本地复制驱动管理器文件" else # 从 Gitee 下载 info "从 Gitee 下载驱动管理器..." local tmp_dir=$(mktemp -d) local zip_url="https://gitee.com/yu-yon/S905L3A/repository/archive/master.zip" if wget -q --show-progress -O "$tmp_dir/repo.zip" "$zip_url" 2>/dev/null || \ curl -sL -o "$tmp_dir/repo.zip" "$zip_url" 2>/dev/null; then cd "$tmp_dir" unzip -q repo.zip 2>/dev/null local dm_dir=$(find . -type d -name "cups-driver-manager" 2>/dev/null | head -1) if [ -n "$dm_dir" ] && [ -d "$dm_dir" ]; then cp -f "$dm_dir/driver_manager.py" "$install_dir/" cp -f "$dm_dir/cups-driver-manager.service" /etc/systemd/system/ 2>/dev/null || true fi cd - > /dev/null rm -rf "$tmp_dir" else warn "驱动管理器下载失败,跳过安装" return 1 fi fi # 设置权限 chmod +x "$install_dir/driver_manager.py" # 生成随机密码 local admin_pass=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 8) # 更新 systemd 服务文件中的密码 if [ -f /etc/systemd/system/cups-driver-manager.service ]; then sed -i "s/DRIVER_MANAGER_PASSWORD=admin/DRIVER_MANAGER_PASSWORD=$admin_pass/" /etc/systemd/system/cups-driver-manager.service else # 手动创建服务文件 cat > /etc/systemd/system/cups-driver-manager.service << EOF [Unit] Description=CUPS Printer Driver Manager After=network.target cups.service Wants=cups.service [Service] Type=simple User=root WorkingDirectory=$install_dir ExecStart=/usr/bin/python3 $install_dir/driver_manager.py --port 632 Restart=on-failure RestartSec=5 Environment=DRIVER_MANAGER_PASSWORD=$admin_pass [Install] WantedBy=multi-user.target EOF fi # 启动服务 systemctl daemon-reload systemctl enable cups-driver-manager systemctl restart cups-driver-manager # 保存密码到文件 echo "$admin_pass" > "$install_dir/.password" chmod 600 "$install_dir/.password" success "驱动管理器安装完成" info "驱动管理器密码: $admin_pass" # 导出变量供后续使用 DRIVER_MANAGER_PASSWORD="$admin_pass" } # 安装虚拟PDF打印机(用于测试连接) install_pdf_printer() { info "安装虚拟 PDF 打印机..." # 安装 cups-pdf 包(Debian 13+ 包名改为 printer-driver-cups-pdf) apt install -y printer-driver-cups-pdf 2>/dev/null || apt install -y cups-pdf 2>/dev/null || { warn "cups-pdf 包不可用,跳过虚拟 PDF 打印机安装" return 0 } # 等待 CUPS 服务就绪 sleep 2 # 检查是否已存在 PDF 打印机 if lpstat -p PDF 2>/dev/null | grep -q "PDF"; then info "PDF 打印机已存在,跳过创建" else # 添加 PDF 虚拟打印机 # 使用 lpadmin 命令创建打印机 lpadmin -p PDF \ -v cups-pdf:/ \ -E \ -m lsb/usr/cups-pdf/CUPS-PDF_opt.ppd \ -D "虚拟PDF打印机 (测试用)" \ -L "本地" \ -o printer-is-shared=true # 如果上面的 PPD 文件不存在,尝试其他路径 if ! lpstat -p PDF 2>/dev/null | grep -q "PDF"; then # 尝试使用通用 PPD lpadmin -p PDF \ -v cups-pdf:/ \ -E \ -m raw \ -D "虚拟PDF打印机 (测试用)" \ -L "本地" \ -o printer-is-shared=true 2>/dev/null || true fi # 启用打印机 cupsenable PDF 2>/dev/null || true cupsaccept PDF 2>/dev/null || true fi # 配置 cups-pdf 输出目录 if [ -f /etc/cups/cups-pdf.conf ]; then # 设置输出目录为 /var/spool/cups-pdf/ANONYMOUS (匿名用户) sed -i 's|^Out .*|Out /var/spool/cups-pdf/${USER}|' /etc/cups/cups-pdf.conf # 创建输出目录 mkdir -p /var/spool/cups-pdf/ANONYMOUS chmod 1777 /var/spool/cups-pdf/ANONYMOUS fi # 验证安装 if lpstat -p PDF 2>/dev/null | grep -q "PDF"; then success "虚拟 PDF 打印机安装成功" info "PDF 文件输出目录: /var/spool/cups-pdf/" else warn "虚拟 PDF 打印机安装可能不完整,请在 CUPS 管理界面手动添加" fi } # 配置CUPS configure_cups() { info "配置 CUPS 允许远程访问..." # 备份原配置 cp /etc/cups/cupsd.conf /etc/cups/cupsd.conf.bak # 修改监听地址 sed -i 's/^Listen localhost:631$/Listen 0.0.0.0:631/' /etc/cups/cupsd.conf # 如果没有找到 Listen localhost:631,则添加 if ! grep -q "Listen 0.0.0.0:631" /etc/cups/cupsd.conf; then sed -i '/^Listen/d' /etc/cups/cupsd.conf sed -i '1a Listen 0.0.0.0:631\nListen /run/cups/cups.sock' /etc/cups/cupsd.conf fi # 添加 ServerAlias * 允许任何主机名访问 if ! grep -q "^ServerAlias" /etc/cups/cupsd.conf; then sed -i '/^Listen.*631/a ServerAlias *' /etc/cups/cupsd.conf fi # 禁用强制加密(允许 HTTP 访问) if ! grep -q "^DefaultEncryption" /etc/cups/cupsd.conf; then sed -i '/^ServerAlias/a DefaultEncryption Never' /etc/cups/cupsd.conf fi # 启用网络浏览 if grep -q "^Browsing" /etc/cups/cupsd.conf; then sed -i 's/^Browsing.*/Browsing Yes/' /etc/cups/cupsd.conf else echo "Browsing Yes" >> /etc/cups/cupsd.conf fi # 禁用主机名查找(加速打印任务提交) if ! grep -q "^HostNameLookups" /etc/cups/cupsd.conf; then echo "HostNameLookups Off" >> /etc/cups/cupsd.conf fi # 修改 Policy default 允许匿名打印 # 找到 块并修改 sed -i '//,/<\/Limit>/{ s/Order deny,allow/Order allow,deny/ /Require user/d /Order/a\ Allow all }' /etc/cups/cupsd.conf # 配置访问权限 - 允许所有网络访问 # 先删除现有的 Location 块,然后重新添加 cat > /tmp/cups_locations.conf << 'EOF' # 允许所有网络访问(内网环境使用) Order allow,deny Allow all Order allow,deny Allow all AuthType Default Require user @SYSTEM Order allow,deny Allow all # 允许远程打印 Order allow,deny Allow all Order allow,deny Allow all EOF # 移除旧的 Location 块 sed -i '//d' /etc/cups/cupsd.conf # 添加新的 Location 配置 cat /tmp/cups_locations.conf >> /etc/cups/cupsd.conf rm /tmp/cups_locations.conf success "CUPS 配置完成" } # 主函数 main() { show_banner check_root LOCAL_IP=$(get_ip) info "检测到本机IP: ${LOCAL_IP}" echo "" # 选择驱动 select_drivers echo "" # 询问是否换源 echo -e "${YELLOW}是否将软件源更换为国内镜像(清华大学)?${NC}" echo " 推荐:国内用户选择 Y,可大幅加快下载速度" echo "" read -p "更换国内源? [Y/n]: " change_mirror < /dev/tty change_mirror=${change_mirror:-Y} echo "" # 询问是否配置静态IP echo -e "${YELLOW}是否将当前 IP 配置为静态 IP?${NC}" echo " 推荐:选择 Y,避免 IP 变化导致无法连接打印服务器" echo " 当前 IP: ${LOCAL_IP}" echo "" read -p "配置静态 IP? [Y/n]: " config_static_ip < /dev/tty config_static_ip=${config_static_ip:-Y} echo "" # 询问是否安装驱动管理器 echo -e "${YELLOW}是否安装驱动管理器(Web界面安装打印机驱动)?${NC}" echo " 推荐:选择 Y,可通过网页上传安装 .deb/.ppd/.tar.gz 等驱动" echo " 端口: 632" echo "" read -p "安装驱动管理器? [Y/n]: " install_dm < /dev/tty install_dm=${install_dm:-Y} echo "" # 确认安装 echo -e "${YELLOW}即将执行以下操作:${NC}" local step=1 if [[ "$change_mirror" =~ ^[Yy]$ ]]; then echo " $step. 更换为国内软件源(清华大学)" ((step++)) fi echo " $step. 更新系统软件源" ((step++)) if [[ "$config_static_ip" =~ ^[Yy]$ ]]; then echo " $step. 配置静态 IP 地址 (${LOCAL_IP})" ((step++)) fi echo " $step. 安装 CUPS 和 Avahi" ((step++)) echo " $step. 安装打印机驱动" ((step++)) echo " $step. 配置 CUPS 允许局域网访问" ((step++)) echo " $step. 将当前用户添加到 lpadmin 组" ((step++)) if [[ "$install_dm" =~ ^[Yy]$ ]]; then echo " $step. 安装驱动管理器 (端口 632)" ((step++)) fi echo " $step. 启动并设置开机自启" echo "" read -p "是否继续? [Y/n]: " confirm < /dev/tty confirm=${confirm:-Y} if [[ ! "$confirm" =~ ^[Yy]$ ]]; then echo "已取消" exit 0 fi echo "" info "开始安装..." echo "" # 0. 解决 apt 锁问题 fix_apt_lock # 1. 换源(如果选择) if [[ "$change_mirror" =~ ^[Yy]$ ]]; then change_to_china_mirror fi # 2. 更新系统 info "更新软件源..." apt update success "软件源更新完成" # 3. 配置静态IP(如果选择) if [[ "$config_static_ip" =~ ^[Yy]$ ]]; then configure_static_ip fi # 4. 安装 CUPS 和 Avahi info "安装 CUPS 和 Avahi..." apt install -y cups avahi-daemon wget unzip success "CUPS 和 Avahi 安装完成" # 3. 设置中国时区 info "设置系统时区为中国(Asia/Shanghai)..." timedatectl set-timezone Asia/Shanghai 2>/dev/null || \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime success "时区设置完成:$(date '+%Y-%m-%d %H:%M:%S')" # 4. 安装中文语言包(CUPS汉化) info "安装中文语言包..." apt install -y locales language-pack-zh-hans 2>/dev/null || apt install -y locales 2>/dev/null # 生成中文 locale sed -i 's/# zh_CN.UTF-8 UTF-8/zh_CN.UTF-8 UTF-8/' /etc/locale.gen 2>/dev/null locale-gen zh_CN.UTF-8 2>/dev/null # 设置 CUPS 默认语言为中文 if ! grep -q "DefaultLanguage" /etc/cups/cupsd.conf 2>/dev/null; then echo 'DefaultLanguage zh_CN.UTF-8' >> /etc/cups/cupsd.conf fi # 安装中文 Web 界面模板 install_chinese_templates success "中文语言包安装完成" # 3. 安装驱动 install_drivers success "驱动安装完成" # 4. 配置 CUPS configure_cups # 5. 添加用户到 lpadmin 组 info "将 root 用户添加到 lpadmin 组..." usermod -aG lpadmin root # 如果有其他用户,也添加 CURRENT_USER=$(logname 2>/dev/null || echo "") if [ -n "$CURRENT_USER" ] && [ "$CURRENT_USER" != "root" ]; then usermod -aG lpadmin "$CURRENT_USER" info "将 $CURRENT_USER 用户添加到 lpadmin 组" fi success "用户组配置完成" # 6. 安装驱动管理器(如果选择) if [[ "$install_dm" =~ ^[Yy]$ ]]; then install_driver_manager fi # 7. 启动服务 info "启动 CUPS 服务..." systemctl restart cups systemctl enable cups success "CUPS 服务已启动并设置开机自启" info "启动 Avahi 服务..." systemctl restart avahi-daemon systemctl enable avahi-daemon success "Avahi 服务已启动并设置开机自启" # 更新IP地址(如果配置了静态IP) LOCAL_IP=$(get_ip) # 完成提示 echo "" echo -e "${GREEN}╔══════════════════════════════════════════════════════════╗${NC}" echo -e "${GREEN}║ 安装完成! ║${NC}" echo -e "${GREEN}╚══════════════════════════════════════════════════════════╝${NC}" echo "" if [[ "$config_static_ip" =~ ^[Yy]$ ]]; then echo -e " ${GREEN}[静态IP]${NC} 已配置,IP 地址固定为: ${LOCAL_IP}" echo "" fi echo -e " ${BLUE}┌─────────────────────────────────────────────────────┐${NC}" echo -e " ${BLUE}│${NC} ${YELLOW}CUPS 管理界面${NC} ${BLUE}│${NC}" echo -e " ${BLUE}│${NC} 地址: https://${LOCAL_IP}:631 ${BLUE}│${NC}" echo -e " ${BLUE}│${NC} 用户名: root ${BLUE}│${NC}" echo -e " ${BLUE}│${NC} 密码: 你的 SSH 登录密码 ${BLUE}│${NC}" echo -e " ${BLUE}└─────────────────────────────────────────────────────┘${NC}" echo "" # 检查是否安装了驱动管理器 if systemctl is-active cups-driver-manager >/dev/null 2>&1; then local dm_pass=$(cat /opt/cups-driver-manager/.password 2>/dev/null || echo "admin") echo -e " ${GREEN}┌─────────────────────────────────────────────────────┐${NC}" echo -e " ${GREEN}│${NC} ${YELLOW}驱动管理器 (上传安装驱动)${NC} ${GREEN}│${NC}" echo -e " ${GREEN}│${NC} 地址: http://${LOCAL_IP}:632 ${GREEN}│${NC}" echo -e " ${GREEN}│${NC} ${RED}用户名: admin${NC} ${GREEN}│${NC}" echo -e " ${GREEN}│${NC} ${RED}密码: ${dm_pass}${NC} ${GREEN}│${NC}" echo -e " ${GREEN}│${NC} ${YELLOW}(注意:不是SSH密码!)${NC} ${GREEN}│${NC}" echo -e " ${GREEN}└─────────────────────────────────────────────────────┘${NC}" echo "" fi # 检查是否安装了PDF打印机 if lpstat -p PDF 2>/dev/null | grep -q "PDF"; then echo -e " ${GREEN}[PDF打印机]${NC} 已安装虚拟 PDF 打印机用于测试" echo -e " ${GREEN} ${NC} PDF 输出目录: /var/spool/cups-pdf/" echo "" fi echo -e " ${YELLOW}下一步:${NC}" echo " 1. 用浏览器打开上面的地址" if lpstat -p PDF 2>/dev/null | grep -q "PDF"; then echo " 2. 可使用已安装的 PDF 打印机测试连接" echo " 3. 点击 Administration → Add Printer 添加真实打印机" echo " 4. 勾选 Share This Printer" else echo " 2. 点击 Administration → Add Printer 添加打印机" echo " 3. 勾选 Share This Printer" fi echo "" echo -e " ${YELLOW}客户端连接:${NC}" echo " - Windows: 设置 → 打印机 → 添加打印机" echo " - macOS/iOS: 自动通过 AirPrint 发现" echo " - Android: 安装 Mopria Print Service" echo "" # 检查打印机 echo -e "${BLUE}[检测]${NC} 正在检测 USB 打印机..." if lsusb | grep -i -E "printer|print" > /dev/null 2>&1; then success "检测到 USB 打印机:" lsusb | grep -i -E "printer|print" else warn "未检测到 USB 打印机,请确认打印机已连接" fi echo "" } # 卸载函数 uninstall() { echo -e "${RED}" echo "╔══════════════════════════════════════════════════════════╗" echo "║ CUPS 打印服务卸载程序 ║" echo "╚══════════════════════════════════════════════════════════╝" echo -e "${NC}" echo "" check_root echo -e "${YELLOW}即将卸载以下组件:${NC}" echo " - CUPS 打印服务" echo " - Avahi 服务 (AirPrint)" echo " - CUPS-PDF 虚拟打印机" echo " - 中文界面模板" echo " - 驱动管理器" echo " - 所有打印任务和配置" echo "" read -p "确定要卸载吗? [y/N]: " confirm < /dev/tty confirm=${confirm:-N} if [[ ! "$confirm" =~ ^[Yy]$ ]]; then echo "已取消" exit 0 fi echo "" info "开始卸载..." # 停止服务 info "停止服务..." systemctl stop cups 2>/dev/null || true systemctl stop avahi-daemon 2>/dev/null || true systemctl stop cups-driver-manager 2>/dev/null || true systemctl disable cups 2>/dev/null || true systemctl disable avahi-daemon 2>/dev/null || true systemctl disable cups-driver-manager 2>/dev/null || true # 卸载软件包 info "卸载软件包..." apt remove --purge -y cups cups-common cups-client cups-bsd cups-core-drivers \ cups-daemon cups-filters cups-ipp-utils cups-pdf cups-ppdc \ avahi-daemon 2>/dev/null || true # 删除配置和数据 info "删除配置和数据..." rm -rf /etc/cups rm -rf /var/spool/cups rm -rf /var/spool/cups-pdf rm -rf /var/log/cups rm -rf /usr/share/cups/templates-zh_CN rm -rf /usr/share/cups/templates-zh rm -rf /usr/share/cups/templates-en-backup rm -rf /opt/cups-driver-manager rm -f /etc/systemd/system/cups-driver-manager.service systemctl daemon-reload 2>/dev/null || true # 清理依赖 info "清理依赖..." apt autoremove -y 2>/dev/null || true echo "" echo -e "${GREEN}╔══════════════════════════════════════════════════════════╗${NC}" echo -e "${GREEN}║ 卸载完成! ║${NC}" echo -e "${GREEN}╚══════════════════════════════════════════════════════════╝${NC}" echo "" } # 显示帮助 show_help() { echo "CUPS 打印服务一键配置脚本" echo "" echo "用法:" echo " $0 显示主菜单" echo " $0 --install 直接安装 CUPS 打印服务" echo " $0 --uninstall 直接卸载 CUPS 打印服务" echo " $0 --help 显示此帮助信息" echo "" } # 显示主菜单 show_menu() { clear echo -e "${GREEN}" echo "╔══════════════════════════════════════════════════════════╗" echo "║ CUPS 打印服务一键配置脚本 ║" echo "║ 适用于 Armbian / Debian / Ubuntu ║" echo "╚══════════════════════════════════════════════════════════╝" echo -e "${NC}" echo "" echo " 请选择操作:" echo "" echo " 1) 安装 CUPS 打印服务" echo " 2) 卸载 CUPS 打印服务" echo " 3) 切换为 DHCP 自动获取 IP" echo " 4) 切换为静态 IP(固定当前 IP)" echo " 0) 退出" echo "" read -p " 请输入选项 [1/2/3/4/0]: " choice < /dev/tty case "$choice" in 1) main ;; 2) uninstall ;; 3) check_root configure_dhcp echo "" read -p "按 Enter 返回主菜单..." < /dev/tty show_menu ;; 4) check_root configure_static_ip show_static_ip_result echo "" read -p "按 Enter 返回主菜单..." < /dev/tty show_menu ;; 0) echo "已退出" exit 0 ;; *) echo "无效选项,请重新选择" sleep 1 show_menu ;; esac } # 解析参数并运行 case "${1:-}" in --uninstall|-u) uninstall ;; --install|-i) main ;; --help|-h) show_help ;; "") show_menu ;; *) echo "未知参数: $1" show_help exit 1 ;; esac