#!/bin/bash red(){ echo -e "\033[31m$1\033[0m" } green(){ echo -e "\033[32m$1\033[0m" } # 动态安装软件包 install_package() { local PACKAGE_NAME=$1 if command -v "$PACKAGE_NAME" &> /dev/null; then echo "$PACKAGE_NAME 已安装, 跳过." return 0 fi echo "安装 $PACKAGE_NAME..." sleep 1 local PACKAGE_MANAGER PACKAGE_MANAGER=$(get_package_manager) if [ "$PACKAGE_MANAGER" == "apt-get" ]; then sudo apt-get update sudo apt-get install -y "$PACKAGE_NAME" elif [ "$PACKAGE_MANAGER" == "yum" ]; then sudo yum install -y "$PACKAGE_NAME" else echo "未知的包管理器, 请手动安装 $PACKAGE_NAME." return 1 fi } # 获取系统包管理器 get_package_manager(){ if command -v apt-get &> /dev/null; then echo "apt-get" elif command -v yum &> /dev/null; then echo "yum" else echo "未知的系统包管理器" return 1 # 返回错误状态码 fi } # 检查 jq 是否已安装 check_jq() { if command -v jq >/dev/null 2>&1; then return 0 else echo "jq 未安装" return 1 fi } # 生成密码 gen_password() { local PASS_LENGTH=$1 # 密码长度作为第一个参数 local CHARS='[:alnum:]' # 只允许出现字母和数字 local RAND RAND=$(< /dev/urandom tr -dc "$CHARS" | head -c "$PASS_LENGTH") echo "$RAND" } # URL编码 url_encode() { local STR="$1" local ENCODED="" local I CHAR HEX for ((I = 0; I < ${#STR}; I++)); do CHAR="${STR:$I:1}" case "$CHAR" in [a-zA-Z0-9.~_-]) ENCODED+="$CHAR" ;; *) printf -v HEX '%02X' "'$CHAR" ENCODED+="%$HEX" ;; esac done echo "$ENCODED" } # 检查tuic配置文件 check_config_file(){ local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../" # 脚本文件夹绝对路径 local CONFIG_FILE="$SCRIPT_DIR/../config/config.json" # 检查配置文件是否存在 if [ ! -e "$CONFIG_FILE" ]; then echo "配置文件不存在, 请先生成配置文件." exit 1 fi # 检查配置文件是否为有效的JSON格式 if ! jq '.' "$CONFIG_FILE" >/dev/null 2>&1; then echo "配置文件不是有效的JSON格式, 请重新生成配置文件." exit 1 fi } # 重启docker容器 restart_docker() { local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../" # 脚本文件夹绝对路径 local COMPOSE_FILE="$SCRIPT_DIR/../docker-compose.yml" # 如果容器未运行,提示启动 local RUNNING_COUNT=$(docker compose -f $COMPOSE_FILE ps -q | wc -l) if [ "$RUNNING_COUNT" -eq 0 ]; then read -p "容器未启动,是否启动容器?(y/n): " CHOICE case "$CHOICE" in Y|y) docker compose -f $COMPOSE_FILE up -d return ;; *) echo "已取消启动" return ;; esac fi echo "正在重启容器..." docker compose -f $COMPOSE_FILE down docker compose -f $COMPOSE_FILE up -d } # 展示当前值并询问用户新输入的值 # 用法: ask_update "提示语" "当前值(当前配置文件的值)" # 示例: # NEW_PORT=$(ask_update "请输入新的端口号" "$(jq -r '.inbounds[0].port' $CONFIG_DIR/config.json)") ask_update() { local PROMPT="$1" # 提示语 local CURRENT_VALUE="$2" local INPUT read -p "${PROMPT} [当前: ${CURRENT_VALUE}]: " INPUT # 用户直接回车则保留当前值,否则使用新输入 echo "${INPUT:-$CURRENT_VALUE}" }