139 lines
5.5 KiB
Bash
139 lines
5.5 KiB
Bash
📋 复制
|
|
#!/usr/bin/env bash
|
|
# Generated by shell-gen (https://github.com/yourname/shell-gen)
|
|
# Generator: VNC 远程桌面 (TigerVNC + 多桌面)
|
|
# Generated at: 2026-08-04 14:12:09
|
|
# OS: Ubuntu / Debian / CentOS / RHEL / Rocky / Alma
|
|
set -euo pipefail
|
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
|
|
LOG_PREFIX="[VNC 远程桌面 (TigerVNC + 多桌面)]"
|
|
|
|
log() { echo "${LOG_PREFIX} $*" ; }
|
|
warn() { echo "${LOG_PREFIX} WARN: $*" >&2 ; }
|
|
die() { echo "${LOG_PREFIX} ERROR: $*" >&2 ; exit 1 ; }
|
|
|
|
[ "$(id -u)" -eq 0 ] || die "This script must be run as root. Re-run with sudo."
|
|
|
|
# ---- detect distro ----
|
|
. /etc/os-release 2>/dev/null || true
|
|
DISTRO_ID="${ID:-unknown}"
|
|
DISTRO_LIKE="${ID_LIKE:-}"
|
|
case "$DISTRO_ID" in
|
|
ubuntu|debian) PKG="apt-get"; PKG_INSTALL="DEBIAN_FRONTEND=noninteractive apt-get install -y" ;;
|
|
centos|rhel|rocky|almalinux|ol) PKG="yum"; PKG_INSTALL="yum install -y" ;;
|
|
fedora) PKG="dnf"; PKG_INSTALL="dnf install -y" ;;
|
|
*)
|
|
if echo "$DISTRO_LIKE" | grep -qiE "rhel|centos|fedora"; then
|
|
PKG="yum"; PKG_INSTALL="yum install -y"
|
|
elif echo "$DISTRO_LIKE" | grep -qi "debian"; then
|
|
PKG="apt-get"; PKG_INSTALL="DEBIAN_FRONTEND=noninteractive apt-get install -y"
|
|
else
|
|
die "Unsupported distribution: $DISTRO_ID"
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
log "Detected distro: $DISTRO_ID (package manager: $PKG)"
|
|
|
|
log "Installing VNC + gnome desktop for user 'wxj' on display :15"
|
|
log "Updating apt cache..."
|
|
apt-get update
|
|
log "Installing gnome desktop + TigerVNC..."
|
|
DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
|
ubuntu-desktop-minimal \
|
|
dbus-x11 tigervnc-standalone-server tigervnc-common tigervnc-xorg-extension \
|
|
xvfb x11vnc x11-utils 2>/dev/null || \
|
|
DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
|
gnome-session gnome-shell gnome-terminal nautilus metacity \
|
|
dbus-x11 tigervnc-standalone-server tigervnc-common \
|
|
xvfb x11vnc x11-utils \
|
|
xserver-xorg-video-dummy \
|
|
gnome-shell-extension-desktop-icons-ng gnome-terminal nautilus-extension-gnome-terminal gnome-tweaks
|
|
log "Preparing VNC directory..."
|
|
USER_HOME="$(getent passwd 'wxj' | cut -d: -f6 || echo /root)"
|
|
if [ "$USER_HOME" = "/root" ] && [ "wxj" != "root" ]; then
|
|
warn "getent passwd wxj returned home=/root; assuming /home/wxj"
|
|
USER_HOME="/home/wxj"
|
|
fi
|
|
log "User 'wxj' home: $USER_HOME"
|
|
# Ensure user exists (idempotent — useradd exits 9 if user exists)
|
|
# Force login shell = /bin/bash so systemd User= can run xstartup
|
|
id "wxj" >/dev/null 2>&1 || useradd -m -d "$USER_HOME" -s /bin/bash wxj
|
|
CURRENT_HOME="$(getent passwd "wxj" | cut -d: -f6)"
|
|
if [ "$CURRENT_HOME" != "$USER_HOME" ]; then
|
|
warn "Fixing home for user wxj: $CURRENT_HOME -> $USER_HOME"
|
|
usermod -d "$USER_HOME" -m "wxj" 2>/dev/null || true
|
|
fi
|
|
CURRENT_SHELL="$(getent passwd "wxj" | cut -d: -f7)"
|
|
if [ "$CURRENT_SHELL" != "/bin/bash" ]; then
|
|
warn "Fixing shell for user wxj: $CURRENT_SHELL -> /bin/bash"
|
|
usermod -s /bin/bash "wxj"
|
|
fi
|
|
[ -d /home ] && chmod 755 /home || true
|
|
install -d -o "wxj" -g "wxj" -m 0750 "$USER_HOME"
|
|
install -d -o "wxj" -g "wxj" -m 0700 "$USER_HOME/.vnc"
|
|
|
|
log "Setting VNC password..."
|
|
PASS='Aa123456'
|
|
printf "%s\n" "$PASS" | vncpasswd -f > "$USER_HOME/.vnc/passwd"
|
|
chmod 600 "$USER_HOME/.vnc/passwd"
|
|
chown "wxj":"wxj" "$USER_HOME/.vnc/passwd"
|
|
|
|
log "Writing xstartup (gnome via dbus-launch)..."
|
|
cat > "$USER_HOME/.vnc/xstartup" <<'XSTARTUP_EOF'
|
|
#!/bin/sh
|
|
unset SESSION_MANAGER
|
|
unset DBUS_SESSION_BUS_ADDRESS
|
|
export XDG_CURRENT_DESKTOP=ubuntu:GNOME
|
|
export XDG_SESSION_TYPE=x11
|
|
export GNOME_SHELL_SESSION_MODE=ubuntu
|
|
exec dbus-launch --exit-with-session gnome-session
|
|
XSTARTUP_EOF
|
|
chmod +x "$USER_HOME/.vnc/xstartup"
|
|
|
|
|
|
log "Writing systemd unit vncserver@.service..."
|
|
cat > /etc/systemd/system/vncserver@.service <<'UNIT_EOF'
|
|
[Unit]
|
|
Description=TigerVNC server on display :%i (gnome)
|
|
After=syslog.target network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=wxj
|
|
Group=wxj
|
|
WorkingDirectory=__VNC_HOME__
|
|
ExecStartPre=-/usr/bin/vncserver -kill :%i
|
|
ExecStartPre=-/bin/sh -c 'for f in /tmp/.X%i-lock /tmp/.X11-unix/X%i; do [ -e "$f" ] && rm -f "$f"; done; exit 0'
|
|
ExecStart=/usr/bin/vncserver -fg :%i -geometry 1920x1080 -depth 24 -localhost=0
|
|
ExecStop=/usr/bin/vncserver -kill :%i
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
UNIT_EOF
|
|
# Substitute the placeholder with the actual home path
|
|
sed -i "s|__VNC_HOME__|$USER_HOME|" /etc/systemd/system/vncserver@.service
|
|
log " WorkingDirectory: $(grep ^WorkingDirectory= /etc/systemd/system/vncserver@.service)"
|
|
log " Unit written. Verifying WorkingDirectory..."
|
|
# Check if display :${display} is already in use
|
|
if ss -xlpn 2>/dev/null | grep -q "/tmp/.X11-unix/X15 "; then
|
|
EXISTING="$(ss -xlpn 2>/dev/null | grep "/tmp/.X11-unix/X15 " | head -1)"
|
|
warn "Display :15 is already in use by another X server:"
|
|
warn " $EXISTING"
|
|
warn "This machine likely has a physical desktop on :15."
|
|
warn "Please use a higher display number (e.g. :3 or :10)."
|
|
die "Display :15 is occupied. Aborting."
|
|
fi
|
|
log "Cleaning up stale /tmp/.X11-unix sockets (as root)..."
|
|
rm -f /tmp/.X15-lock /tmp/.X11-unix/X15 2>/dev/null || true
|
|
pkill -f "Xvnc.*:15 " 2>/dev/null || true
|
|
pkill -f "Xtigervnc.*:15" 2>/dev/null || true
|
|
systemctl daemon-reload
|
|
systemctl enable vncserver@15.service
|
|
systemctl restart vncserver@15.service
|
|
sleep 2
|
|
systemctl --no-pager status vncserver@15.service || true
|
|
|
|
log "Verifying port..."
|
|
ss -ltn | grep ":5915" || warn "Port 5915 not listening yet, give it 5s."
|
|
log "Done. Connect with VNC Viewer to <server>:5915 (desktop: gnome)" |