From 71780131e83d90981a52c34ebb751d2855a3305c Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 9 Apr 2026 03:59:21 +0800 Subject: [PATCH 1/4] Add macOS support for rustdesk installer --- README.md | 176 ++++++---- rustdesktool.sh | 917 +++++++++++++++++++++++++++++++++--------------- 2 files changed, 739 insertions(+), 354 deletions(-) diff --git a/README.md b/README.md index f7e682d..ecc5af8 100644 --- a/README.md +++ b/README.md @@ -1,113 +1,153 @@ -# RustDesk-Server 一键安装脚本 +# RustDesk Server Tool -## 示例 -```sh -# RustDesk-Server x86 一键安装脚本 -# Rep -# You Server:ubuntu -服务状态: [运行中] +一个交互式的 RustDesk Server 安装脚本,现在同时支持: ->~~~~~~~~~~~~~~ rustdesk-server tool ~~~~~~~~~~~~< v: 1.3 +- Linux:使用官方发布的 Linux 预编译包安装 `hbbs` / `hbbr` +- macOS:由于官方发布页没有提供 macOS Server 二进制,本脚本会拉取官方源码并在本机编译,然后用 `launchd` 托管服务 -1: 安装 2: 卸载 +仓库地址: +[https://github.com/sshpc/rustdesktool](https://github.com/sshpc/rustdesktool) -3: 查看状态 4: 查看key +## 支持情况 -5: 启动服务 6: 停止服务 +### Linux -7: 升级脚本 +- 发行版:Ubuntu、Debian、CentOS、Rocky、AlmaLinux、Alpine +- 架构:`amd64`、`arm64` +- 服务管理:`systemd` -q: 退出 +### macOS -请输入命令号: -``` +- 架构:Intel(`amd64`) / Apple Silicon(`arm64`) +- 服务管理:`launchd` +- 安装方式:从官方 `rustdesk/rustdesk-server` 源码编译 -## 安装&卸载 +## macOS 说明 -### 一键安装 -> root 用户 +截至官方 `rustdesk-server` `1.1.15` 发布版本,发布页提供的是 Linux zip/deb 资产,没有 macOS Server 预编译包。 -```sh -wget -N https://raw.githubusercontent.com/sshpc/rustdesktool/main/rustdesktool.sh && chmod +x ./rustdesktool.sh && ./rustdesktool.sh -``` +因此这个脚本在 macOS 上会: -> 再次执行 +1. 下载 `rustdesk/rustdesk-server` 对应版本源码 +2. 本机执行 `cargo build --release` +3. 安装生成的 `hbbs` / `hbbr` +4. 写入 `launchd` plist 到 `/Library/LaunchDaemons` -```sh -./rustdesktool.sh +### macOS 前置依赖 + +先安装这些依赖: + +```bash +xcode-select --install +brew install rust git ``` -### 国内加速链接 -```sh -wget -N https://gh.ddlc.top/https://raw.githubusercontent.com/sshpc/rustdesktool/main/rustdesktool.sh && chmod +x ./rustdesktool.sh && ./rustdesktool.sh +说明: + +- 建议用普通用户运行脚本,脚本在需要写系统目录时会自动调用 `sudo` +- 首次编译 RustDesk Server 可能需要几分钟 + +## 使用方法 + +### 1. 克隆仓库 + +```bash +git clone https://github.com/sshpc/rustdesktool.git +cd rustdesktool +chmod +x rustdesktool.sh ``` -```sh -wget -N https://gh-proxy.com/https://raw.githubusercontent.com/sshpc/rustdesktool/main/rustdesktool.sh && chmod +x ./rustdesktool.sh && ./rustdesktool.sh + +### 2. 启动脚本 + +```bash +./rustdesktool.sh ``` -## 客户端下载 -官方地址 -https://rustdesk.com/download +如果你希望直接以 root 方式运行 Linux 安装,也可以: -支持 (Windows、Ubuntu、Mac、Android..) +```bash +sudo ./rustdesktool.sh +``` -## 客户端配置 +## 菜单功能 ->默认安装后使用的是官方的服务器,需要换成自己的 +- `Install` +- `Uninstall` +- `View status` +- `View public key` +- `Start service` +- `Stop service` +- `Update script` - 设置 → 网络 -* ID服务器地址:<你的服务器IP> -* 中继服务器地址:<你的服务器IP> -* API服务器地址:留空 -* 秘钥:你的服务器公钥(安装后获得) +说明: +- 这个分支里 `Update script` 已禁用,避免把本地的 macOS 适配改回上游原版脚本 -## 其他信息 +## 安装目录 -### 默认安装目录 -/usr/local/rustdesk-sever +默认安装目录: -### 服务安装目录 +```text +/usr/local/rustdesk-server +``` -/usr/lib/systemd/system/RustDeskHbbr.service -/usr/lib/systemd/system/RustDeskHbbs.service +公钥位置: +```text +/usr/local/rustdesk-server/id_ed25519.pub +``` -### 秘钥位置 -默认安装目录下的 id_ed25519.pub +日志目录: ->自定义秘钥:安装后手动替换安装目录下的 id_ed25519.pub 和 id_ed25519 +```text +/usr/local/rustdesk-server/logs +``` -### 端口 +## 服务文件位置 ->若连接失败,请检查防火墙端口是否打开 +### Linux -hbbs 监听21115(tcp), 21116(tcp/udp), 21118(tcp) +```text +/usr/lib/systemd/system/RustDeskHbbs.service +/usr/lib/systemd/system/RustDeskHbbr.service +``` -hbbr 监听21117(tcp), 21119(tcp) +### macOS -* 21115 -> hbbs用作NAT类型测试 -* 21116/UDP -> hbbs用作ID注册与心跳服务 -* 21116/TCP -> hbbs用作TCP打洞与连接服务 -* 21117 -> hbbr中继服务 -* 21118、21119 -> 网页客户端 +```text +/Library/LaunchDaemons/com.rustdesk.hbbs.plist +/Library/LaunchDaemons/com.rustdesk.hbbr.plist +``` +## 客户端配置 -### 官方 rep: +RustDesk 客户端中设置: -https://github.com/rustdesk/rustdesk-server +- ID Server:你的服务器 IP 或域名 +- Relay Server:你的服务器 IP 或域名 +- API Server:留空 +- Key:服务端生成的公钥 -## Star History +## 端口 - - - - - Star History Chart - - +请确保这些端口已放行: +- `21115/tcp` +- `21116/tcp` +- `21116/udp` +- `21117/tcp` +- `21118/tcp` +- `21119/tcp` +作用说明: +- `21115`:NAT 测试 +- `21116/tcp`:TCP 打洞与连接 +- `21116/udp`:ID 注册与心跳 +- `21117`:Relay 服务 +- `21118` / `21119`:Web 相关端口 +## 官方项目 +- RustDesk Server: [https://github.com/rustdesk/rustdesk-server](https://github.com/rustdesk/rustdesk-server) +- RustDesk Client: [https://rustdesk.com/download](https://rustdesk.com/download) diff --git a/rustdesktool.sh b/rustdesktool.sh index 30ec825..7ffda14 100755 --- a/rustdesktool.sh +++ b/rustdesktool.sh @@ -1,333 +1,363 @@ -#!/bin/bash -export LANG=en_US.UTF-8 - - -#安装目录 -installdirectory='/usr/local/rustdesk-server' -#官方版本号 -rustdeskserverversion='1.1.15' -# 配置文件下载代理主机列表(github加速) -proxyhost=( +#!/usr/bin/env bash + +set -u + +export LANG="${LANG:-en_US.UTF-8}" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +RUSTDESK_SERVER_VERSION="${RUSTDESK_SERVER_VERSION:-1.1.15}" +INSTALL_DIRECTORY="${INSTALL_DIRECTORY:-/usr/local/rustdesk-server}" +MACOS_BUILD_DIRECTORY="${MACOS_BUILD_DIRECTORY:-${TMPDIR:-/tmp}/rustdesktool-build}" +LINUX_SERVICE_DIRECTORY="${LINUX_SERVICE_DIRECTORY:-/usr/lib/systemd/system}" +MACOS_SERVICE_DIRECTORY="${MACOS_SERVICE_DIRECTORY:-/Library/LaunchDaemons}" +HBBS_SERVICE_NAME="RustDeskHbbs" +HBBR_SERVICE_NAME="RustDeskHbbr" +HBBS_LAUNCHD_LABEL="com.rustdesk.hbbs" +HBBR_LAUNCHD_LABEL="com.rustdesk.hbbr" +HBBS_LAUNCHD_PLIST="${MACOS_SERVICE_DIRECTORY}/${HBBS_LAUNCHD_LABEL}.plist" +HBBR_LAUNCHD_PLIST="${MACOS_SERVICE_DIRECTORY}/${HBBR_LAUNCHD_LABEL}.plist" +LOG_DIRECTORY="${INSTALL_DIRECTORY}/logs" +TIMEOUT_SECONDS=10 +RELEASE="unknown" +ARCH_LABEL="unknown" +DOWNLOAD_ARCHIVE_NAME="" +DOWNLOAD_EXTRACTED_DIRECTORY="" +INSTALL_TYPE="" +REMOVE_TYPE="" +UPDATE_TYPE="" +SUDO="" +PLATFORM_SUPPORTS_NATIVE_BINARIES="false" + +PROXY_HOSTS=( "https://gh.ddlc.top" "https://gh-proxy.com" "https://edgeone.gh-proxy.com" "https://cdn.gh-proxy.com" "https://hk.gh-proxy.com" ) -#下载超时时间 -timeout=3 -installType='' -removeType='' -upgrade='' -release='linux' +color_red() { + printf '\033[0;31m%b\033[0m\n' "$1" +} -#字体颜色定义 -_red() { - printf '\033[0;31;31m%b\033[0m' "$1" - echo +color_green() { + printf '\033[0;32m%b\033[0m\n' "$1" } -_green() { - printf '\033[0;31;32m%b\033[0m' "$1" - echo + +color_yellow() { + printf '\033[0;33m%b\033[0m\n' "$1" } -_yellow() { - printf '\033[0;31;33m%b\033[0m' "$1" - echo + +color_blue() { + printf '\033[0;36m%b\033[0m\n' "$1" } -_blue() { - printf '\033[0;31;36m%b\033[0m' "$1" + +wait_input() { echo -} -waitinput() { + read -r -n1 -p "Press any key to continue... (Ctrl+C to quit)" echo - read -n1 -r -p "按任意键继续...(退出 Ctrl+C)" } -# 加载动画 + loading() { - local pids=("$@") + local pid="$1" local delay=0.1 - local spinstr='|/-\' - tput civis # 隐藏光标 - - while :; do - local all_done=true - for pid in "${pids[@]}"; do - if kill -0 "$pid" 2>/dev/null; then - all_done=false - local temp=${spinstr#?} - printf "\r\033[0;31;36m[ %c ] loading ...\033[0m" "$spinstr" - local spinstr=$temp${spinstr%"$temp"} - sleep $delay - fi - done - [[ $all_done == true ]] && break + local spin='|/-\' + + if command -v tput >/dev/null 2>&1; then + tput civis 2>/dev/null || true + fi + + while kill -0 "$pid" 2>/dev/null; do + local first_char="${spin%${spin#?}}" + printf "\r\033[0;36m[ %s ] working...\033[0m" "$first_char" + spin="${spin#?}${first_char}" + sleep "$delay" done - - tput cnorm # 恢复光标 - printf "\r\033[K" # 清除行 + + if command -v tput >/dev/null 2>&1; then + tput cnorm 2>/dev/null || true + fi + + printf "\r\033[K" +} + +run_privileged() { + if [[ -n "$SUDO" ]]; then + "$SUDO" "$@" + else + "$@" + fi +} + +require_command() { + local command_name="$1" + local hint="$2" + if ! command -v "$command_name" >/dev/null 2>&1; then + color_red "Missing dependency: ${command_name}" + color_yellow "$hint" + exit 1 + fi } -# 通用下载函数:从镜像列表中依次尝试下载文件 download_file() { local url="$1" - local path="$2" - local output="" - local dest="" - if [[ -n "$path" ]]; then - dest="$path" - else - dest="." - fi - for base in "${proxyhost[@]}"; do - output="${dest}/$(basename "$url")" - ( - wget -q --timeout="$timeout" "${base}/$url" -O "$output" > /dev/null 2>&1 - ) & - local pid=$! - loading $pid - wait $pid - if [[ -s "$output" ]]; then - return 0 - fi + local output="$2" + local candidates=("$url") + local candidate="" + + for base in "${PROXY_HOSTS[@]}"; do + candidates+=("${base}/${url}") done - return 1 -} + rm -f "$output" -#菜单渲染 -menu() { - printf "\033[H\033[2J" - _green '# RustDesk-Server x86 一键安装脚本' - _green '# Rep ' - _blue '# You Server:'${release} - _blue "服务状态: [$(check_rustdesk_status)]" - echo - _blue ">~~~~~~~~~~~~~~ rustdesk-server tool ~~~~~~~~~~~~< v: $rustdeskserverversion" - echo - options=("$@") - num_options=${#options[@]} - # 计算数组中的字符最大长度 - max_len=0 - for ((i = 0; i < num_options; i++)); do - # 获取当前字符串的长度 - str_len=${#options[i]} - - # 更新最大长度 - if ((str_len > max_len)); then - max_len=$str_len + for candidate in "${candidates[@]}"; do + if command -v curl >/dev/null 2>&1; then + if curl -fsL --connect-timeout "$TIMEOUT_SECONDS" "$candidate" -o "$output" >/dev/null 2>&1; then + return 0 + fi + elif command -v wget >/dev/null 2>&1; then + if wget -q --timeout="$TIMEOUT_SECONDS" "$candidate" -O "$output" >/dev/null 2>&1; then + return 0 + fi + else + color_red "curl or wget is required for downloading files." + return 1 fi done - # 渲染菜单 - for ((i = 0; i < num_options; i += 4)); do - printf "%s%*s " "$((i / 2 + 1)): ${options[i]}" "$((max_len - ${#options[i]}))" - if [[ "${options[i + 2]}" != "" ]]; then printf "$((i / 2 + 2)): ${options[i + 2]}"; fi - echo - echo - done - printf '\033[0;31;31m%b\033[0m' "q: 退出 " - echo - echo - # 获取用户输入 - read -ep "请输入命令号: " number - if [[ $number -ge 1 && $number -le $((num_options / 2)) ]]; then - #找到函数名索引 - action_index=$((2 * (number - 1) + 1)) - #函数名赋值 - parentfun=${options[action_index]} - #函数执行 - ${options[action_index]} - waitinput - main - elif [[ $number == 'q' ]]; then - echo - exit - else - echo - _red '输入有误 回车返回首页' - waitinput - main - fi + + rm -f "$output" + return 1 } -#检查系统 -checkSystem() { - - if grep -qi "centos\|red hat" /etc/os-release; then - release="centos" - installType='yum -y install' - removeType='yum -y remove' - upgrade="yum update -y --skip-broken" - elif grep -qi "ubuntu" /etc/os-release; then - release="ubuntu" - installType='apt -y install' - removeType='apt -y autoremove' - upgrade="apt update" - elif grep -qi "debian" /etc/os-release; then - release="debian" - installType='apt -y install' - removeType='apt -y autoremove' - upgrade="apt update" - elif grep -qi "alpine" /etc/os-release; then - release="alpine" - installType='apk add' - upgrade="apk update" - removeType='apk del' - else - _red "不支持此系统" - _red "$(cat /etc/issue)" - _red "$(cat /proc/version)" +ensure_linux_package_tools() { + if [[ "$RELEASE" == "linux" && -z "$INSTALL_TYPE" ]]; then + color_red "Unsupported Linux distribution." exit 1 fi } +ensure_linux_dependency() { + local binary_name="$1" + local package_name="$2" + if command -v "$binary_name" >/dev/null 2>&1; then + return 0 + fi -#脚本升级 -updateself() { + ensure_linux_package_tools + color_yellow "Installing missing package: ${package_name}" + run_privileged bash -lc "${INSTALL_TYPE} ${package_name}" || { + color_red "Failed to install ${package_name}." + exit 1 + } +} + +ensure_macos_prerequisites() { + require_command "git" "Install Xcode Command Line Tools first: xcode-select --install" + require_command "cargo" "Install Rust first, for example: brew install rust" - _blue '下载最新版脚本' - if ! download_file "https://raw.githubusercontent.com/sshpc/rustdesktool/main/rustdesktool.sh"; then - _red "rustdesktool.sh 下载失败!" - return 1 + if ! xcode-select -p >/dev/null 2>&1; then + color_red "Xcode Command Line Tools are not installed." + color_yellow "Run: xcode-select --install" + exit 1 fi - chmod +x ./rustdesktool.sh - _green "脚本更新成功" - exec bash ./rustdesktool.sh } -check_rustdesk_status() { - local hbbs_service="/usr/lib/systemd/system/RustDeskHbbs.service" - local hbbr_service="/usr/lib/systemd/system/RustDeskHbbr.service" +detect_architecture() { + local machine_arch + machine_arch="$(uname -m)" + + case "$machine_arch" in + x86_64|amd64) + ARCH_LABEL="amd64" + DOWNLOAD_ARCHIVE_NAME="rustdesk-server-linux-amd64.zip" + DOWNLOAD_EXTRACTED_DIRECTORY="amd64" + ;; + arm64|aarch64) + ARCH_LABEL="arm64" + DOWNLOAD_ARCHIVE_NAME="rustdesk-server-linux-arm64v8.zip" + DOWNLOAD_EXTRACTED_DIRECTORY="arm64v8" + ;; + *) + ARCH_LABEL="$machine_arch" + DOWNLOAD_ARCHIVE_NAME="" + DOWNLOAD_EXTRACTED_DIRECTORY="" + ;; + esac +} - # 判断是否安装 - if [[ ! -f "$hbbs_service" || ! -f "$hbbr_service" ]]; then - echo "未安装" - return +check_system() { + local uname_out + uname_out="$(uname -s)" + + case "$uname_out" in + Linux) + RELEASE="linux" + PLATFORM_SUPPORTS_NATIVE_BINARIES="true" + if [[ -f /etc/os-release ]]; then + if grep -qi "centos\|red hat\|rocky\|almalinux" /etc/os-release; then + INSTALL_TYPE='yum -y install' + REMOVE_TYPE='yum -y remove' + UPDATE_TYPE='yum -y update' + elif grep -qi "ubuntu\|debian" /etc/os-release; then + INSTALL_TYPE='apt -y install' + REMOVE_TYPE='apt -y autoremove' + UPDATE_TYPE='apt update' + elif grep -qi "alpine" /etc/os-release; then + INSTALL_TYPE='apk add' + REMOVE_TYPE='apk del' + UPDATE_TYPE='apk update' + fi + fi + ;; + Darwin) + RELEASE="macos" + PLATFORM_SUPPORTS_NATIVE_BINARIES="false" + ;; + *) + color_red "Unsupported operating system: ${uname_out}" + exit 1 + ;; + esac + + detect_architecture + + if [[ "$RELEASE" == "linux" && -z "$INSTALL_TYPE" ]]; then + color_red "This Linux distribution is not supported by the script." + exit 1 fi - # 判断是否运行 - if systemctl is-active --quiet RustDeskHbbs && systemctl is-active --quiet RustDeskHbbr; then - echo "运行中" - else - echo "未运行" + if [[ "$RELEASE" == "macos" && "$ARCH_LABEL" != "amd64" && "$ARCH_LABEL" != "arm64" ]]; then + color_red "macOS is only supported on amd64 and arm64." + exit 1 fi -} - + if [[ "$RELEASE" == "linux" && "$ARCH_LABEL" != "amd64" && "$ARCH_LABEL" != "arm64" ]]; then + color_red "Linux native install currently supports amd64 and arm64 only." + exit 1 + fi -#查看状态 -viewstatus() { - echo - _blue 'RustDeskHbbs status:' - systemctl status RustDeskHbbs | awk '/Active/' - _blue 'RustDeskHbbr status:' - systemctl status RustDeskHbbr | awk '/Active/' - _blue 'net status:' - netstat -tuln | grep -E ":(21115|21116|21117|21118|21119)\b" + if [[ "$(id -u)" -eq 0 ]]; then + SUDO="" + elif command -v sudo >/dev/null 2>&1; then + SUDO="sudo" + else + color_red "This script needs root privileges or sudo." + exit 1 + fi } -startservice() { - _blue "启动服务" - ( - systemctl start RustDeskHbbs > /dev/null 2>&1 - systemctl start RustDeskHbbr > /dev/null 2>&1 - ) & - local pid=$! - loading $pid - wait $pid - _green "服务已启动" +linux_hbbs_service_file() { + printf '%s/%s.service' "$LINUX_SERVICE_DIRECTORY" "$HBBS_SERVICE_NAME" } -stopservice() { - _blue "停止服务" - ( - systemctl stop RustDeskHbbs > /dev/null 2>&1 - systemctl stop RustDeskHbbr > /dev/null 2>&1 - ) & - local pid=$! - loading $pid - wait $pid - _yellow "服务已停止" +linux_hbbr_service_file() { + printf '%s/%s.service' "$LINUX_SERVICE_DIRECTORY" "$HBBR_SERVICE_NAME" } -viewkey() { - echo - _blue '公钥:' - cat $installdirectory/id_ed25519.pub - echo - echo +linux_service_installed() { + [[ -f "$(linux_hbbs_service_file)" && -f "$(linux_hbbr_service_file)" ]] } -#卸载 -uninstall() { - read -rp "确认卸载?(y/N): " c - [[ $c == y ]] || return - stopservice - - systemctl disable RustDeskHbbs - systemctl disable RustDeskHbbr - - rm -rf $installdirectory - rm -rf /usr/lib/systemd/system/RustDeskHbbs.service - rm -rf /usr/lib/systemd/system/RustDeskHbbr.service +macos_service_installed() { + [[ -f "$HBBS_LAUNCHD_PLIST" && -f "$HBBR_LAUNCHD_PLIST" ]] +} - _blue '已卸载' - echo +linux_services_running() { + systemctl is-active --quiet "$HBBS_SERVICE_NAME" && systemctl is-active --quiet "$HBBR_SERVICE_NAME" } -#安装 -install() { +macos_services_running() { + pgrep -f "${INSTALL_DIRECTORY}/hbbs" >/dev/null 2>&1 && pgrep -f "${INSTALL_DIRECTORY}/hbbr" >/dev/null 2>&1 +} - #检查是否已安装 - if [ -f "/usr/lib/systemd/system/RustDeskHbbr.service" ]; then - _yellow '检测到文件存在 卸载旧版...' - uninstall +check_rustdesk_status() { + if [[ "$RELEASE" == "linux" ]]; then + if ! linux_service_installed; then + echo "not installed" + return + fi + if linux_services_running; then + echo "running" + else + echo "stopped" + fi + return fi - _blue "开始安装" - mkdir -p $installdirectory - - # 检查并安装 wget - if ! command -v wget >/dev/null 2>&1; then - _yellow "未检测到 wget,正在安装..." - ${installType} wget || { _red "wget 安装失败"; exit 1; } + if ! macos_service_installed; then + echo "not installed" + return fi - # 检查并安装 unzip - if ! command -v unzip >/dev/null 2>&1; then - _yellow "未检测到 unzip,正在安装..." - ${installType} unzip || { _red "unzip 安装失败"; exit 1; } + if macos_services_running; then + echo "running" + else + echo "stopped" fi +} - _blue "下载安装文件" - if ! download_file "https://github.com/rustdesk/rustdesk-server/releases/download/$rustdeskserverversion/rustdesk-server-linux-amd64.zip" "$installdirectory"; then - _red "rustdesk-server-linux-amd64.zip下载失败!" - exit 1 - fi +menu() { + local options=("$@") + local num_options="${#options[@]}" + local max_len=0 + local i=0 + local label="" + local number="" + local action_index=0 - _blue "解压文件" - ( - unzip $installdirectory/rustdesk-server-linux-amd64.zip -d $installdirectory > /dev/null 2>&1 - ) & - local pid=$! - loading $pid - wait $pid + printf "\033[H\033[2J" + color_green "# RustDesk Server installer" + color_green "# Repo " + color_blue "# Platform: ${RELEASE} (${ARCH_LABEL})" + color_blue "# Install mode: $(if [[ "$RELEASE" == "linux" ]]; then echo "official Linux binary"; else echo "build from source for macOS"; fi)" + color_blue "# Service status: [$(check_rustdesk_status)]" + echo + color_blue ">~~~~~~~~~~~~~~ rustdesk-server tool ~~~~~~~~~~~~< v: ${RUSTDESK_SERVER_VERSION}" + echo - mv $installdirectory/amd64/* $installdirectory/ + for ((i = 0; i < num_options; i += 2)); do + label="${options[i]}" + if (( ${#label} > max_len )); then + max_len="${#label}" + fi + done + + for ((i = 0; i < num_options; i += 4)); do + printf "%s%*s " "$((i / 2 + 1)): ${options[i]}" "$((max_len - ${#options[i]}))" "" + if [[ -n "${options[i + 2]:-}" ]]; then + printf "%s" "$((i / 2 + 2)): ${options[i + 2]}" + fi + echo + echo + done - rm $installdirectory/rustdesk-server-linux-amd64.zip - rm -r $installdirectory/amd64 + color_red "q: quit" + echo + read -r -p "Select an action: " number - chmod +x $installdirectory/hbbr - chmod +x $installdirectory/hbbs + if [[ "$number" == "q" ]]; then + exit 0 + fi - if [ ! -f "/usr/lib/systemd/system/RustDeskHbbr.service" ]; then - #文件不存在 - touch /usr/lib/systemd/system/RustDeskHbbr.service + if [[ "$number" =~ ^[0-9]+$ ]] && (( number >= 1 && number <= num_options / 2 )); then + action_index=$((2 * (number - 1) + 1)) + "${options[action_index]}" + wait_input + main + return fi - cat </usr/lib/systemd/system/RustDeskHbbr.service + color_red "Invalid selection." + wait_input + main +} + +write_linux_service_files() { + run_privileged mkdir -p "$LINUX_SERVICE_DIRECTORY" + + run_privileged tee "$(linux_hbbr_service_file)" >/dev/null </usr/lib/systemd/system/RustDeskHbbs.service + run_privileged tee "$(linux_hbbs_service_file)" >/dev/null </dev/null < + + + + Label + ${HBBR_LAUNCHD_LABEL} + ProgramArguments + + ${INSTALL_DIRECTORY}/hbbr + + WorkingDirectory + ${INSTALL_DIRECTORY} + RunAtLoad + + KeepAlive + + StandardOutPath + ${LOG_DIRECTORY}/hbbr.log + StandardErrorPath + ${LOG_DIRECTORY}/hbbr.err.log + + +EOF + + run_privileged tee "$HBBS_LAUNCHD_PLIST" >/dev/null < + + + + Label + ${HBBS_LAUNCHD_LABEL} + ProgramArguments + + ${INSTALL_DIRECTORY}/hbbs + + WorkingDirectory + ${INSTALL_DIRECTORY} + RunAtLoad + + KeepAlive + + StandardOutPath + ${LOG_DIRECTORY}/hbbs.log + StandardErrorPath + ${LOG_DIRECTORY}/hbbs.err.log + + +EOF + + run_privileged chmod 644 "$HBBS_LAUNCHD_PLIST" "$HBBR_LAUNCHD_PLIST" +} + +launchd_bootout_if_loaded() { + local label="$1" + if run_privileged launchctl print "system/${label}" >/dev/null 2>&1; then + run_privileged launchctl bootout "system/${label}" >/dev/null 2>&1 || true + fi +} + +start_linux_services() { + color_blue "Starting RustDesk services..." + run_privileged systemctl start "$HBBS_SERVICE_NAME" + run_privileged systemctl start "$HBBR_SERVICE_NAME" + color_green "RustDesk services started." +} + +start_macos_services() { + color_blue "Starting launchd services..." + launchd_bootout_if_loaded "$HBBR_LAUNCHD_LABEL" + launchd_bootout_if_loaded "$HBBS_LAUNCHD_LABEL" + run_privileged launchctl bootstrap system "$HBBR_LAUNCHD_PLIST" + run_privileged launchctl bootstrap system "$HBBS_LAUNCHD_PLIST" + run_privileged launchctl enable "system/${HBBR_LAUNCHD_LABEL}" >/dev/null 2>&1 || true + run_privileged launchctl enable "system/${HBBS_LAUNCHD_LABEL}" >/dev/null 2>&1 || true + run_privileged launchctl kickstart -k "system/${HBBR_LAUNCHD_LABEL}" >/dev/null 2>&1 || true + run_privileged launchctl kickstart -k "system/${HBBS_LAUNCHD_LABEL}" >/dev/null 2>&1 || true + color_green "launchd services started." +} + +stop_linux_services() { + color_blue "Stopping RustDesk services..." + run_privileged systemctl stop "$HBBS_SERVICE_NAME" >/dev/null 2>&1 || true + run_privileged systemctl stop "$HBBR_SERVICE_NAME" >/dev/null 2>&1 || true + color_yellow "RustDesk services stopped." +} + +stop_macos_services() { + color_blue "Stopping launchd services..." + launchd_bootout_if_loaded "$HBBS_LAUNCHD_LABEL" + launchd_bootout_if_loaded "$HBBR_LAUNCHD_LABEL" + color_yellow "launchd services stopped." +} + +start_service() { + if [[ "$RELEASE" == "linux" ]]; then + start_linux_services + else + start_macos_services + fi +} + +stop_service() { + if [[ "$RELEASE" == "linux" ]]; then + stop_linux_services + else + stop_macos_services + fi +} + +view_status() { echo - #启动服务 - startservice + if [[ "$RELEASE" == "linux" ]]; then + color_blue "RustDeskHbbs status:" + systemctl status "$HBBS_SERVICE_NAME" --no-pager 2>/dev/null | awk '/Active:|Loaded:/' + color_blue "RustDeskHbbr status:" + systemctl status "$HBBR_SERVICE_NAME" --no-pager 2>/dev/null | awk '/Active:|Loaded:/' + color_blue "Listening ports:" + if command -v ss >/dev/null 2>&1; then + ss -lntu | grep -E ':(21115|21116|21117|21118|21119)\b' || true + else + netstat -tuln 2>/dev/null | grep -E ':(21115|21116|21117|21118|21119)\b' || true + fi + return + fi - #printf "\033[H\033[2J" + color_blue "launchd services:" + if run_privileged launchctl print "system/${HBBS_LAUNCHD_LABEL}" >/dev/null 2>&1; then + run_privileged launchctl print "system/${HBBS_LAUNCHD_LABEL}" 2>/dev/null | awk -F'= ' '/state =/ {print "hbbs state: " $2; exit}' + else + echo "hbbs state: not loaded" + fi + + if run_privileged launchctl print "system/${HBBR_LAUNCHD_LABEL}" >/dev/null 2>&1; then + run_privileged launchctl print "system/${HBBR_LAUNCHD_LABEL}" 2>/dev/null | awk -F'= ' '/state =/ {print "hbbr state: " $2; exit}' + else + echo "hbbr state: not loaded" + fi + + color_blue "Running processes:" + pgrep -fal "${INSTALL_DIRECTORY}/hbbs" || true + pgrep -fal "${INSTALL_DIRECTORY}/hbbr" || true + + color_blue "Listening ports:" + lsof -nP -iTCP -sTCP:LISTEN | grep -E ':(21115|21116|21117|21118|21119)' || true + lsof -nP -iUDP | grep -E ':(21115|21116|21117|21118|21119)' || true +} + +view_key() { + local key_file="${INSTALL_DIRECTORY}/id_ed25519.pub" + echo + if [[ -f "$key_file" ]]; then + color_blue "Public key:" + cat "$key_file" + else + color_yellow "Public key not found yet." + color_yellow "Start the service first, then wait a few seconds and try again." + fi echo - _green '安装完成' - viewkey +} + +print_public_ip() { + local public_ip="" + if command -v curl >/dev/null 2>&1; then + public_ip="$(curl -fsL --connect-timeout "$TIMEOUT_SECONDS" https://ipinfo.io/ip 2>/dev/null || true)" + elif command -v wget >/dev/null 2>&1; then + public_ip="$(wget -q -T "$TIMEOUT_SECONDS" -O- https://ipinfo.io/ip 2>/dev/null || true)" + fi + + if [[ -n "$public_ip" ]]; then + color_green "Public IP:" + echo "$public_ip" + echo + fi +} + +install_linux() { + local archive_path="${TMPDIR:-/tmp}/${DOWNLOAD_ARCHIVE_NAME}.$$" + local download_url="https://github.com/rustdesk/rustdesk-server/releases/download/${RUSTDESK_SERVER_VERSION}/${DOWNLOAD_ARCHIVE_NAME}" + + ensure_linux_dependency "unzip" "unzip" + + if linux_service_installed; then + color_yellow "Existing Linux service detected. Reinstalling cleanly..." + perform_uninstall "force" + fi + + color_blue "Preparing installation directory..." + run_privileged mkdir -p "$INSTALL_DIRECTORY" + run_privileged mkdir -p "$LOG_DIRECTORY" + + color_blue "Downloading official RustDesk Server binary for Linux..." + if ! download_file "$download_url" "$archive_path"; then + color_red "Failed to download ${DOWNLOAD_ARCHIVE_NAME}." + exit 1 + fi + + color_blue "Extracting archive..." + run_privileged unzip -oq "$archive_path" -d "$INSTALL_DIRECTORY" + run_privileged install -m 755 "${INSTALL_DIRECTORY}/${DOWNLOAD_EXTRACTED_DIRECTORY}/hbbs" "${INSTALL_DIRECTORY}/hbbs" + run_privileged install -m 755 "${INSTALL_DIRECTORY}/${DOWNLOAD_EXTRACTED_DIRECTORY}/hbbr" "${INSTALL_DIRECTORY}/hbbr" + run_privileged rm -rf "${INSTALL_DIRECTORY}/${DOWNLOAD_EXTRACTED_DIRECTORY}" + rm -f "$archive_path" + + color_blue "Writing systemd service files..." + write_linux_service_files + + start_linux_services + sleep 2 - local ip="$(wget -q -T10 -O- ipinfo.io/ip)" - _green '公网 IP:' - echo $ip echo - _yellow "请手动放行防火墙 TCP & UDP端口 21115-21119" + color_green "Linux installation finished." + view_key + print_public_ip + color_yellow "Please allow TCP/UDP ports 21115-21119 in your firewall." +} + +install_macos() { + local source_archive="${MACOS_BUILD_DIRECTORY}/rustdesk-server-${RUSTDESK_SERVER_VERSION}.tar.gz" + local source_url="https://github.com/rustdesk/rustdesk-server/archive/refs/tags/${RUSTDESK_SERVER_VERSION}.tar.gz" + local extracted_source_dir="${MACOS_BUILD_DIRECTORY}/rustdesk-server-${RUSTDESK_SERVER_VERSION}" + local macos_source_directory="${MACOS_BUILD_DIRECTORY}/rustdesk-server" + + ensure_macos_prerequisites + + if macos_service_installed; then + color_yellow "Existing macOS service detected. Reinstalling cleanly..." + perform_uninstall "force" + fi + + color_blue "Preparing installation directory..." + run_privileged mkdir -p "$INSTALL_DIRECTORY" + run_privileged mkdir -p "$LOG_DIRECTORY" + mkdir -p "$MACOS_BUILD_DIRECTORY" + + color_blue "Downloading official RustDesk Server source tarball..." + if ! download_file "$source_url" "$source_archive"; then + color_red "Failed to download RustDesk Server source for ${RUSTDESK_SERVER_VERSION}." + exit 1 + fi + + rm -rf "$extracted_source_dir" "$macos_source_directory" + color_blue "Extracting source archive..." + tar -xzf "$source_archive" -C "$MACOS_BUILD_DIRECTORY" + mv "$extracted_source_dir" "$macos_source_directory" + rm -f "$source_archive" + + color_blue "Building hbbs and hbbr from source for macOS..." + ( + cd "$macos_source_directory" || exit 1 + cargo build --release >/dev/null 2>&1 + ) & + local build_pid=$! + loading "$build_pid" + if ! wait "$build_pid"; then + color_red "cargo build failed." + color_yellow "Please verify Rust toolchain and Xcode Command Line Tools are installed." + exit 1 + fi + + run_privileged install -m 755 "${macos_source_directory}/target/release/hbbs" "${INSTALL_DIRECTORY}/hbbs" + run_privileged install -m 755 "${macos_source_directory}/target/release/hbbr" "${INSTALL_DIRECTORY}/hbbr" + + color_blue "Writing launchd plists..." + write_macos_launchd_files + + start_macos_services + sleep 3 + echo + color_green "macOS installation finished." + view_key + print_public_ip + color_yellow "Please allow TCP/UDP ports 21115-21119 in the macOS firewall or upstream router." +} + +install() { + if [[ "$RELEASE" == "linux" ]]; then + install_linux + else + install_macos + fi +} +uninstall_linux() { + stop_linux_services || true + run_privileged systemctl disable "$HBBS_SERVICE_NAME" >/dev/null 2>&1 || true + run_privileged systemctl disable "$HBBR_SERVICE_NAME" >/dev/null 2>&1 || true + run_privileged rm -rf "$INSTALL_DIRECTORY" + run_privileged rm -f "$(linux_hbbs_service_file)" "$(linux_hbbr_service_file)" + run_privileged systemctl daemon-reload >/dev/null 2>&1 || true } +uninstall_macos() { + stop_macos_services || true + run_privileged rm -rf "$INSTALL_DIRECTORY" + run_privileged rm -f "$HBBS_LAUNCHD_PLIST" "$HBBR_LAUNCHD_PLIST" + rm -rf "$MACOS_BUILD_DIRECTORY" +} + +perform_uninstall() { + local mode="${1:-ask}" + local confirm="" + if [[ "$mode" != "force" ]]; then + read -r -p "Confirm uninstall? (y/N): " confirm + [[ "$confirm" == "y" || "$confirm" == "Y" ]] || return 0 + fi + + if [[ "$RELEASE" == "linux" ]]; then + uninstall_linux + else + uninstall_macos + fi + + color_blue "RustDesk Server has been uninstalled." +} + +uninstall() { + perform_uninstall "ask" +} + +update_self() { + color_yellow "Self-update is disabled in this macOS-capable fork." + color_yellow "If you want newer upstream changes, merge them through git and keep the macOS patches." +} -#主函数 main() { - options=("安装" install "卸载" uninstall "查看状态" viewstatus "查看key" viewkey "启动服务" startservice "停止服务" stopservice "升级脚本" updateself) + local options=( + "Install" install + "Uninstall" uninstall + "View status" view_status + "View public key" view_key + "Start service" start_service + "Stop service" stop_service + "Update script" update_self + ) menu "${options[@]}" } -checkSystem +check_system main From d757303379ef7a71705efacfaba9f4b1c1741393 Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 9 Apr 2026 04:07:58 +0800 Subject: [PATCH 2/4] Add direct-install link instructions --- README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/README.md b/README.md index ecc5af8..623affe 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,38 @@ chmod +x rustdesktool.sh sudo ./rustdesktool.sh ``` +## 发布后的一键使用链接 + +如果你把这个仓库上传到你自己的 GitHub,例如: + +```text +https://github.com/<你的用户名>/<你的仓库名> +``` + +那么可以像原项目一样提供这种一键使用方式。 + +### 标准链接 + +```bash +curl -fsSL https://raw.githubusercontent.com/<你的用户名>/<你的仓库名>/main/rustdesktool.sh -o rustdesktool.sh && chmod +x ./rustdesktool.sh && ./rustdesktool.sh +``` + +### 国内加速链接 + +```bash +curl -fsSL https://gh.ddlc.top/https://raw.githubusercontent.com/<你的用户名>/<你的仓库名>/main/rustdesktool.sh -o rustdesktool.sh && chmod +x ./rustdesktool.sh && ./rustdesktool.sh +``` + +```bash +curl -fsSL https://gh-proxy.com/https://raw.githubusercontent.com/<你的用户名>/<你的仓库名>/main/rustdesktool.sh -o rustdesktool.sh && chmod +x ./rustdesktool.sh && ./rustdesktool.sh +``` + +说明: + +- 这里用 `curl` 而不是 `wget`,因为 macOS 默认自带 `curl` +- 上传到 GitHub 后,把 `<你的用户名>` 和 `<你的仓库名>` 替换成真实值即可 +- 如果你的默认分支不是 `main`,需要把链接里的 `main` 改成实际分支名 + ## 菜单功能 - `Install` From d91fd00834f8688c50983a6bcaeb11c4a74004b3 Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 9 Apr 2026 04:16:07 +0800 Subject: [PATCH 3/4] Translate interactive prompts to Chinese --- rustdesktool.sh | 166 ++++++++++++++++++++++++------------------------ 1 file changed, 83 insertions(+), 83 deletions(-) diff --git a/rustdesktool.sh b/rustdesktool.sh index 7ffda14..65045db 100755 --- a/rustdesktool.sh +++ b/rustdesktool.sh @@ -54,7 +54,7 @@ color_blue() { wait_input() { echo - read -r -n1 -p "Press any key to continue... (Ctrl+C to quit)" + read -r -n1 -p "按任意键继续...(Ctrl+C 退出)" echo } @@ -69,7 +69,7 @@ loading() { while kill -0 "$pid" 2>/dev/null; do local first_char="${spin%${spin#?}}" - printf "\r\033[0;36m[ %s ] working...\033[0m" "$first_char" + printf "\r\033[0;36m[ %s ] 处理中...\033[0m" "$first_char" spin="${spin#?}${first_char}" sleep "$delay" done @@ -93,7 +93,7 @@ require_command() { local command_name="$1" local hint="$2" if ! command -v "$command_name" >/dev/null 2>&1; then - color_red "Missing dependency: ${command_name}" + color_red "缺少依赖:${command_name}" color_yellow "$hint" exit 1 fi @@ -121,7 +121,7 @@ download_file() { return 0 fi else - color_red "curl or wget is required for downloading files." + color_red "下载文件需要 curl 或 wget。" return 1 fi done @@ -132,7 +132,7 @@ download_file() { ensure_linux_package_tools() { if [[ "$RELEASE" == "linux" && -z "$INSTALL_TYPE" ]]; then - color_red "Unsupported Linux distribution." + color_red "暂不支持当前 Linux 发行版。" exit 1 fi } @@ -146,20 +146,20 @@ ensure_linux_dependency() { fi ensure_linux_package_tools - color_yellow "Installing missing package: ${package_name}" + color_yellow "正在安装缺少的依赖:${package_name}" run_privileged bash -lc "${INSTALL_TYPE} ${package_name}" || { - color_red "Failed to install ${package_name}." + color_red "${package_name} 安装失败。" exit 1 } } ensure_macos_prerequisites() { - require_command "git" "Install Xcode Command Line Tools first: xcode-select --install" - require_command "cargo" "Install Rust first, for example: brew install rust" + require_command "git" "请先安装 Xcode Command Line Tools:xcode-select --install" + require_command "cargo" "请先安装 Rust,例如:brew install rust" if ! xcode-select -p >/dev/null 2>&1; then - color_red "Xcode Command Line Tools are not installed." - color_yellow "Run: xcode-select --install" + color_red "尚未安装 Xcode Command Line Tools。" + color_yellow "请先执行:xcode-select --install" exit 1 fi } @@ -216,7 +216,7 @@ check_system() { PLATFORM_SUPPORTS_NATIVE_BINARIES="false" ;; *) - color_red "Unsupported operating system: ${uname_out}" + color_red "暂不支持当前操作系统:${uname_out}" exit 1 ;; esac @@ -224,17 +224,17 @@ check_system() { detect_architecture if [[ "$RELEASE" == "linux" && -z "$INSTALL_TYPE" ]]; then - color_red "This Linux distribution is not supported by the script." + color_red "这个脚本暂不支持当前 Linux 发行版。" exit 1 fi if [[ "$RELEASE" == "macos" && "$ARCH_LABEL" != "amd64" && "$ARCH_LABEL" != "arm64" ]]; then - color_red "macOS is only supported on amd64 and arm64." + color_red "macOS 目前仅支持 amd64 和 arm64。" exit 1 fi if [[ "$RELEASE" == "linux" && "$ARCH_LABEL" != "amd64" && "$ARCH_LABEL" != "arm64" ]]; then - color_red "Linux native install currently supports amd64 and arm64 only." + color_red "Linux 原生安装目前仅支持 amd64 和 arm64。" exit 1 fi @@ -243,7 +243,7 @@ check_system() { elif command -v sudo >/dev/null 2>&1; then SUDO="sudo" else - color_red "This script needs root privileges or sudo." + color_red "这个脚本需要 root 权限或 sudo。" exit 1 fi } @@ -275,26 +275,26 @@ macos_services_running() { check_rustdesk_status() { if [[ "$RELEASE" == "linux" ]]; then if ! linux_service_installed; then - echo "not installed" + echo "未安装" return fi if linux_services_running; then - echo "running" + echo "运行中" else - echo "stopped" + echo "已停止" fi return fi if ! macos_service_installed; then - echo "not installed" + echo "未安装" return fi if macos_services_running; then - echo "running" + echo "运行中" else - echo "stopped" + echo "已停止" fi } @@ -308,13 +308,13 @@ menu() { local action_index=0 printf "\033[H\033[2J" - color_green "# RustDesk Server installer" - color_green "# Repo " - color_blue "# Platform: ${RELEASE} (${ARCH_LABEL})" - color_blue "# Install mode: $(if [[ "$RELEASE" == "linux" ]]; then echo "official Linux binary"; else echo "build from source for macOS"; fi)" - color_blue "# Service status: [$(check_rustdesk_status)]" + color_green "# RustDesk Server 一键安装脚本" + color_green "# 项目地址 " + color_blue "# 平台:$(if [[ "$RELEASE" == "linux" ]]; then echo "Linux"; else echo "macOS"; fi) (${ARCH_LABEL})" + color_blue "# 安装方式:$(if [[ "$RELEASE" == "linux" ]]; then echo "官方 Linux 二进制"; else echo "macOS 本地源码编译"; fi)" + color_blue "# 服务状态:[$(check_rustdesk_status)]" echo - color_blue ">~~~~~~~~~~~~~~ rustdesk-server tool ~~~~~~~~~~~~< v: ${RUSTDESK_SERVER_VERSION}" + color_blue ">~~~~~~~~~~~~~~ rustdesk-server 工具 ~~~~~~~~~~~~< 版本:${RUSTDESK_SERVER_VERSION}" echo for ((i = 0; i < num_options; i += 2)); do @@ -333,9 +333,9 @@ menu() { echo done - color_red "q: quit" + color_red "q: 退出" echo - read -r -p "Select an action: " number + read -r -p "请输入操作编号: " number if [[ "$number" == "q" ]]; then exit 0 @@ -349,7 +349,7 @@ menu() { return fi - color_red "Invalid selection." + color_red "输入有误,请重新选择。" wait_input main } @@ -463,14 +463,14 @@ launchd_bootout_if_loaded() { } start_linux_services() { - color_blue "Starting RustDesk services..." + color_blue "正在启动 RustDesk 服务..." run_privileged systemctl start "$HBBS_SERVICE_NAME" run_privileged systemctl start "$HBBR_SERVICE_NAME" - color_green "RustDesk services started." + color_green "RustDesk 服务已启动。" } start_macos_services() { - color_blue "Starting launchd services..." + color_blue "正在启动 launchd 服务..." launchd_bootout_if_loaded "$HBBR_LAUNCHD_LABEL" launchd_bootout_if_loaded "$HBBS_LAUNCHD_LABEL" run_privileged launchctl bootstrap system "$HBBR_LAUNCHD_PLIST" @@ -479,21 +479,21 @@ start_macos_services() { run_privileged launchctl enable "system/${HBBS_LAUNCHD_LABEL}" >/dev/null 2>&1 || true run_privileged launchctl kickstart -k "system/${HBBR_LAUNCHD_LABEL}" >/dev/null 2>&1 || true run_privileged launchctl kickstart -k "system/${HBBS_LAUNCHD_LABEL}" >/dev/null 2>&1 || true - color_green "launchd services started." + color_green "launchd 服务已启动。" } stop_linux_services() { - color_blue "Stopping RustDesk services..." + color_blue "正在停止 RustDesk 服务..." run_privileged systemctl stop "$HBBS_SERVICE_NAME" >/dev/null 2>&1 || true run_privileged systemctl stop "$HBBR_SERVICE_NAME" >/dev/null 2>&1 || true - color_yellow "RustDesk services stopped." + color_yellow "RustDesk 服务已停止。" } stop_macos_services() { - color_blue "Stopping launchd services..." + color_blue "正在停止 launchd 服务..." launchd_bootout_if_loaded "$HBBS_LAUNCHD_LABEL" launchd_bootout_if_loaded "$HBBR_LAUNCHD_LABEL" - color_yellow "launchd services stopped." + color_yellow "launchd 服务已停止。" } start_service() { @@ -516,11 +516,11 @@ view_status() { echo if [[ "$RELEASE" == "linux" ]]; then - color_blue "RustDeskHbbs status:" + color_blue "RustDeskHbbs 状态:" systemctl status "$HBBS_SERVICE_NAME" --no-pager 2>/dev/null | awk '/Active:|Loaded:/' - color_blue "RustDeskHbbr status:" + color_blue "RustDeskHbbr 状态:" systemctl status "$HBBR_SERVICE_NAME" --no-pager 2>/dev/null | awk '/Active:|Loaded:/' - color_blue "Listening ports:" + color_blue "监听端口:" if command -v ss >/dev/null 2>&1; then ss -lntu | grep -E ':(21115|21116|21117|21118|21119)\b' || true else @@ -529,24 +529,24 @@ view_status() { return fi - color_blue "launchd services:" + color_blue "launchd 服务:" if run_privileged launchctl print "system/${HBBS_LAUNCHD_LABEL}" >/dev/null 2>&1; then - run_privileged launchctl print "system/${HBBS_LAUNCHD_LABEL}" 2>/dev/null | awk -F'= ' '/state =/ {print "hbbs state: " $2; exit}' + run_privileged launchctl print "system/${HBBS_LAUNCHD_LABEL}" 2>/dev/null | awk -F'= ' '/state =/ {print "hbbs 状态: " $2; exit}' else - echo "hbbs state: not loaded" + echo "hbbs 状态: 未加载" fi if run_privileged launchctl print "system/${HBBR_LAUNCHD_LABEL}" >/dev/null 2>&1; then - run_privileged launchctl print "system/${HBBR_LAUNCHD_LABEL}" 2>/dev/null | awk -F'= ' '/state =/ {print "hbbr state: " $2; exit}' + run_privileged launchctl print "system/${HBBR_LAUNCHD_LABEL}" 2>/dev/null | awk -F'= ' '/state =/ {print "hbbr 状态: " $2; exit}' else - echo "hbbr state: not loaded" + echo "hbbr 状态: 未加载" fi - color_blue "Running processes:" + color_blue "运行中的进程:" pgrep -fal "${INSTALL_DIRECTORY}/hbbs" || true pgrep -fal "${INSTALL_DIRECTORY}/hbbr" || true - color_blue "Listening ports:" + color_blue "监听端口:" lsof -nP -iTCP -sTCP:LISTEN | grep -E ':(21115|21116|21117|21118|21119)' || true lsof -nP -iUDP | grep -E ':(21115|21116|21117|21118|21119)' || true } @@ -555,11 +555,11 @@ view_key() { local key_file="${INSTALL_DIRECTORY}/id_ed25519.pub" echo if [[ -f "$key_file" ]]; then - color_blue "Public key:" + color_blue "公钥:" cat "$key_file" else - color_yellow "Public key not found yet." - color_yellow "Start the service first, then wait a few seconds and try again." + color_yellow "暂未找到公钥文件。" + color_yellow "请先启动服务,等待几秒后再试。" fi echo } @@ -573,7 +573,7 @@ print_public_ip() { fi if [[ -n "$public_ip" ]]; then - color_green "Public IP:" + color_green "公网 IP:" echo "$public_ip" echo fi @@ -586,38 +586,38 @@ install_linux() { ensure_linux_dependency "unzip" "unzip" if linux_service_installed; then - color_yellow "Existing Linux service detected. Reinstalling cleanly..." + color_yellow "检测到已存在的 Linux 服务,正在重新安装..." perform_uninstall "force" fi - color_blue "Preparing installation directory..." + color_blue "正在准备安装目录..." run_privileged mkdir -p "$INSTALL_DIRECTORY" run_privileged mkdir -p "$LOG_DIRECTORY" - color_blue "Downloading official RustDesk Server binary for Linux..." + color_blue "正在下载官方 Linux 版 RustDesk Server..." if ! download_file "$download_url" "$archive_path"; then - color_red "Failed to download ${DOWNLOAD_ARCHIVE_NAME}." + color_red "${DOWNLOAD_ARCHIVE_NAME} 下载失败。" exit 1 fi - color_blue "Extracting archive..." + color_blue "正在解压安装包..." run_privileged unzip -oq "$archive_path" -d "$INSTALL_DIRECTORY" run_privileged install -m 755 "${INSTALL_DIRECTORY}/${DOWNLOAD_EXTRACTED_DIRECTORY}/hbbs" "${INSTALL_DIRECTORY}/hbbs" run_privileged install -m 755 "${INSTALL_DIRECTORY}/${DOWNLOAD_EXTRACTED_DIRECTORY}/hbbr" "${INSTALL_DIRECTORY}/hbbr" run_privileged rm -rf "${INSTALL_DIRECTORY}/${DOWNLOAD_EXTRACTED_DIRECTORY}" rm -f "$archive_path" - color_blue "Writing systemd service files..." + color_blue "正在写入 systemd 服务文件..." write_linux_service_files start_linux_services sleep 2 echo - color_green "Linux installation finished." + color_green "Linux 安装完成。" view_key print_public_ip - color_yellow "Please allow TCP/UDP ports 21115-21119 in your firewall." + color_yellow "请在防火墙中放行 TCP/UDP 端口 21115-21119。" } install_macos() { @@ -629,28 +629,28 @@ install_macos() { ensure_macos_prerequisites if macos_service_installed; then - color_yellow "Existing macOS service detected. Reinstalling cleanly..." + color_yellow "检测到已存在的 macOS 服务,正在重新安装..." perform_uninstall "force" fi - color_blue "Preparing installation directory..." + color_blue "正在准备安装目录..." run_privileged mkdir -p "$INSTALL_DIRECTORY" run_privileged mkdir -p "$LOG_DIRECTORY" mkdir -p "$MACOS_BUILD_DIRECTORY" - color_blue "Downloading official RustDesk Server source tarball..." + color_blue "正在下载官方 RustDesk Server 源码包..." if ! download_file "$source_url" "$source_archive"; then - color_red "Failed to download RustDesk Server source for ${RUSTDESK_SERVER_VERSION}." + color_red "RustDesk Server ${RUSTDESK_SERVER_VERSION} 源码下载失败。" exit 1 fi rm -rf "$extracted_source_dir" "$macos_source_directory" - color_blue "Extracting source archive..." + color_blue "正在解压源码包..." tar -xzf "$source_archive" -C "$MACOS_BUILD_DIRECTORY" mv "$extracted_source_dir" "$macos_source_directory" rm -f "$source_archive" - color_blue "Building hbbs and hbbr from source for macOS..." + color_blue "正在为 macOS 编译 hbbs 和 hbbr..." ( cd "$macos_source_directory" || exit 1 cargo build --release >/dev/null 2>&1 @@ -658,25 +658,25 @@ install_macos() { local build_pid=$! loading "$build_pid" if ! wait "$build_pid"; then - color_red "cargo build failed." - color_yellow "Please verify Rust toolchain and Xcode Command Line Tools are installed." + color_red "cargo 编译失败。" + color_yellow "请确认 Rust 工具链和 Xcode Command Line Tools 已安装。" exit 1 fi run_privileged install -m 755 "${macos_source_directory}/target/release/hbbs" "${INSTALL_DIRECTORY}/hbbs" run_privileged install -m 755 "${macos_source_directory}/target/release/hbbr" "${INSTALL_DIRECTORY}/hbbr" - color_blue "Writing launchd plists..." + color_blue "正在写入 launchd 配置文件..." write_macos_launchd_files start_macos_services sleep 3 echo - color_green "macOS installation finished." + color_green "macOS 安装完成。" view_key print_public_ip - color_yellow "Please allow TCP/UDP ports 21115-21119 in the macOS firewall or upstream router." + color_yellow "请在 macOS 防火墙或上游路由器中放行 TCP/UDP 端口 21115-21119。" } install() { @@ -707,7 +707,7 @@ perform_uninstall() { local mode="${1:-ask}" local confirm="" if [[ "$mode" != "force" ]]; then - read -r -p "Confirm uninstall? (y/N): " confirm + read -r -p "确认卸载吗?(y/N): " confirm [[ "$confirm" == "y" || "$confirm" == "Y" ]] || return 0 fi @@ -717,7 +717,7 @@ perform_uninstall() { uninstall_macos fi - color_blue "RustDesk Server has been uninstalled." + color_blue "RustDesk Server 已卸载。" } uninstall() { @@ -725,19 +725,19 @@ uninstall() { } update_self() { - color_yellow "Self-update is disabled in this macOS-capable fork." - color_yellow "If you want newer upstream changes, merge them through git and keep the macOS patches." + color_yellow "这个支持 macOS 的分支已禁用脚本自更新。" + color_yellow "如果需要同步上游更新,请通过 git 合并,并保留当前的 macOS 适配修改。" } main() { local options=( - "Install" install - "Uninstall" uninstall - "View status" view_status - "View public key" view_key - "Start service" start_service - "Stop service" stop_service - "Update script" update_self + "安装" install + "卸载" uninstall + "查看状态" view_status + "查看公钥" view_key + "启动服务" start_service + "停止服务" stop_service + "更新脚本" update_self ) menu "${options[@]}" } From f0b1aabbc9dbc7919ce0382122ca441ac07b91d7 Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 9 Apr 2026 04:21:33 +0800 Subject: [PATCH 4/4] Customize README for signyf repository --- README.md | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 623affe..5e7ab15 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ - macOS:由于官方发布页没有提供 macOS Server 二进制,本脚本会拉取官方源码并在本机编译,然后用 `launchd` 托管服务 仓库地址: -[https://github.com/sshpc/rustdesktool](https://github.com/sshpc/rustdesktool) +[https://github.com/signyf/rustdesktool](https://github.com/signyf/rustdesktool) ## 支持情况 @@ -24,7 +24,7 @@ ## macOS 说明 -截至官方 `rustdesk-server` `1.1.15` 发布版本,发布页提供的是 Linux zip/deb 资产,没有 macOS Server 预编译包。 +截至官方 `rustdesk-server` `1.1.15` 版本,发布页提供的是 Linux 资产,没有 macOS Server 预编译包。 因此这个脚本在 macOS 上会: @@ -52,8 +52,9 @@ brew install rust git ### 1. 克隆仓库 ```bash -git clone https://github.com/sshpc/rustdesktool.git +git clone https://github.com/signyf/rustdesktool.git cd rustdesktool +git checkout codex/macos-support chmod +x rustdesktool.sh ``` @@ -69,51 +70,45 @@ chmod +x rustdesktool.sh sudo ./rustdesktool.sh ``` -## 发布后的一键使用链接 +## 一键使用链接 -如果你把这个仓库上传到你自己的 GitHub,例如: - -```text -https://github.com/<你的用户名>/<你的仓库名> -``` - -那么可以像原项目一样提供这种一键使用方式。 +当前可直接使用的分支是 `codex/macos-support`,可以直接运行: ### 标准链接 ```bash -curl -fsSL https://raw.githubusercontent.com/<你的用户名>/<你的仓库名>/main/rustdesktool.sh -o rustdesktool.sh && chmod +x ./rustdesktool.sh && ./rustdesktool.sh +curl -fsSL https://raw.githubusercontent.com/signyf/rustdesktool/codex/macos-support/rustdesktool.sh -o rustdesktool.sh && chmod +x ./rustdesktool.sh && ./rustdesktool.sh ``` ### 国内加速链接 ```bash -curl -fsSL https://gh.ddlc.top/https://raw.githubusercontent.com/<你的用户名>/<你的仓库名>/main/rustdesktool.sh -o rustdesktool.sh && chmod +x ./rustdesktool.sh && ./rustdesktool.sh +curl -fsSL https://gh.ddlc.top/https://raw.githubusercontent.com/signyf/rustdesktool/codex/macos-support/rustdesktool.sh -o rustdesktool.sh && chmod +x ./rustdesktool.sh && ./rustdesktool.sh ``` ```bash -curl -fsSL https://gh-proxy.com/https://raw.githubusercontent.com/<你的用户名>/<你的仓库名>/main/rustdesktool.sh -o rustdesktool.sh && chmod +x ./rustdesktool.sh && ./rustdesktool.sh +curl -fsSL https://gh-proxy.com/https://raw.githubusercontent.com/signyf/rustdesktool/codex/macos-support/rustdesktool.sh -o rustdesktool.sh && chmod +x ./rustdesktool.sh && ./rustdesktool.sh ``` 说明: - 这里用 `curl` 而不是 `wget`,因为 macOS 默认自带 `curl` -- 上传到 GitHub 后,把 `<你的用户名>` 和 `<你的仓库名>` 替换成真实值即可 -- 如果你的默认分支不是 `main`,需要把链接里的 `main` 改成实际分支名 +- 当前命令使用的是 `codex/macos-support` 分支 +- 如果你后面把这些修改合并进 `main`,只需要把链接里的 `codex/macos-support` 改成 `main` ## 菜单功能 -- `Install` -- `Uninstall` -- `View status` -- `View public key` -- `Start service` -- `Stop service` -- `Update script` +- `安装` +- `卸载` +- `查看状态` +- `查看公钥` +- `启动服务` +- `停止服务` +- `更新脚本` 说明: -- 这个分支里 `Update script` 已禁用,避免把本地的 macOS 适配改回上游原版脚本 +- 这个分支里 `更新脚本` 已禁用,避免把本地的 macOS 适配改回上游原版脚本 ## 安装目录