diff --git a/README.md b/README.md index 9bbe1a7..d515007 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ # 使用须知 -- 运行本项目建议使用root用户,或者使用 sudo 提权。 - 使用过程中如遇到问题,请优先查已有的 [issues](https://github.com/wanhebin/clash-for-linux/issues)。 - 在进行issues提交前,请替换提交内容中是敏感信息(例如:订阅地址)。 - 本项目是基于 [clash](https://github.com/Dreamacro/clash) 、[yacd](https://github.com/haishanh/yacd) 进行的配置整合,关于clash、yacd的详细配置请去原项目查看。 @@ -18,6 +17,8 @@ - 运行前请手动更改`.env`文件中的`CLASH_URL`变量值,否则无法正常运行。 - 当前在RHEL系列和Debian系列Linux系统中测试过,其他系列可能需要适当修改脚本。 - 支持 x86_64/aarch64 平台 +- 如果配置已经下载过,用户可以通过 `--skip-download-config` 参数跳过下载配置文件的步骤。 +- 如果用户不希望写入 /etc/profile.d/clash.sh,可以使用 `--skip-edit-profile` 参数跳过写入操作。 > **注意**:当你在使用此项目时,遇到任何无法独自解决的问题请优先前往 [Issues](https://github.com/wanhebin/clash-for-linux/issues) 寻找解决方法。由于空闲时间有限,后续将不再对Issues中 “已经解答”、“已有解决方案” 的问题进行重复性的回答。 diff --git a/icon/Clash_Logo.png b/icon/Clash_Logo.png new file mode 100755 index 0000000..c624b94 Binary files /dev/null and b/icon/Clash_Logo.png differ diff --git a/icon/README.md b/icon/README.md new file mode 100755 index 0000000..d99061b --- /dev/null +++ b/icon/README.md @@ -0,0 +1,13 @@ +# Clash Logo 图标 + +请将 Clash Logo 图标文件 `Clash_Logo.png` 放置在此目录下。 + +你可以从以下位置获取 Clash Logo: +1. 从官方仓库下载 +2. 从其他 Clash 客户端提取 +3. 使用任何 Clash 相关的 Logo 图片,并重命名为 `Clash_Logo.png` + +图标要求: +- 文件名必须是:`Clash_Logo.png` +- 建议尺寸:128x128 像素或更大 +- 格式:PNG(透明背景) \ No newline at end of file diff --git a/shutdown.sh b/shutdown.sh index c2ba4e7..ed46f88 100644 --- a/shutdown.sh +++ b/shutdown.sh @@ -1,5 +1,22 @@ #!/bin/bash +# 初始化跳过编辑profile标志 +SKIP_EDIT_PROFILE=false + +# 处理命令行参数 +while [[ $# -gt 0 ]]; do + case $1 in + --skip-edit-profile) + SKIP_EDIT_PROFILE=true + shift + ;; + *) + echo "未知参数: $1" + exit 1 + ;; + esac +done + # 关闭clash服务 PID_NUM=`ps -ef | grep [c]lash-linux-a | wc -l` PID=`ps -ef | grep [c]lash-linux-a | awk '{print $2}'` @@ -9,6 +26,20 @@ if [ $PID_NUM -ne 0 ]; then fi # 清除环境变量 -> /etc/profile.d/clash.sh +if [ "$SKIP_EDIT_PROFILE" = false ]; then + if [ "$(id -u)" -eq 0 ]; then + > /etc/profile.d/clash.sh + else + echo "错误:需要 root 权限才能修改 /etc/profile.d/clash.sh" >&2 + fi +fi + +# 检查并关闭系统托盘图标 +PID_NUM=`ps -ef | grep [y]ad | grep -i clash | wc -l` +PID=`ps -ef | grep [y]ad | grep -i clash | awk '{print $2}'` +if [ $PID_NUM -ne 0 ]; then + kill -9 $PID + echo -e "\n[INFO] 已移除系统托盘图标" +fi echo -e "\n服务关闭成功,请执行以下命令关闭系统代理:proxy_off\n" diff --git a/start.sh b/start.sh index d11dcb4..1cf339b 100644 --- a/start.sh +++ b/start.sh @@ -9,6 +9,7 @@ export Server_Dir=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd) # 加载.env变量文件 +echo "正在加载环境变量..." source $Server_Dir/.env # 给二进制启动程序、脚本等添加可执行权限 @@ -24,16 +25,88 @@ Conf_Dir="$Server_Dir/conf" Temp_Dir="$Server_Dir/temp" Log_Dir="$Server_Dir/logs" -# 将 CLASH_URL 变量的值赋给 URL 变量,并检查 CLASH_URL 是否为空 -URL=${CLASH_URL:?Error: CLASH_URL variable is not set or empty} - # 获取 CLASH_SECRET 值,如果不存在则生成一个随机数 Secret=${CLASH_SECRET:-$(openssl rand -hex 32)} +# 初始化跳过下载配置标志 +SKIP_DOWNLOAD_CONFIG=false + +# 初始化跳过编辑profile标志 +SKIP_EDIT_PROFILE=false + +# 初始化跳过系统托盘图标标志 +SKIP_TRAY_ICON=false + +# 处理命令行参数 +while [[ $# -gt 0 ]]; do + case $1 in + --skip-download-config) + SKIP_DOWNLOAD_CONFIG=true + shift + ;; + --skip-edit-profile) + SKIP_EDIT_PROFILE=true + shift + ;; + --skip-tray-icon) + SKIP_TRAY_ICON=true + shift + ;; + *) + echo "未知参数: $1" + exit 1 + ;; + esac +done #################### 函数定义 #################### +# 检查依赖是否安装 +check_dependencies() { + if ! command -v yad &> /dev/null; then + echo -e "\033[33m[WARN] 未检测到 yad,尝试安装...\033[0m" + if command -v apt &> /dev/null; then + sudo apt update && sudo apt install -y yad + elif command -v yum &> /dev/null; then + sudo yum install -y yad + elif command -v dnf &> /dev/null; then + sudo dnf install -y yad + else + echo -e "\033[31m[ERROR] 无法安装 yad,请手动安装后重试\033[0m" + return 1 + fi + fi + return 0 +} + +# 启动系统托盘图标 +start_tray_icon() { + local icon_path="$Server_Dir/icon/Clash_Logo.png" + + # 检查图标文件是否存在 + if [ ! -f "$icon_path" ]; then + echo -e "\033[31m[ERROR] 未找到图标文件: $icon_path\033[0m" + return 1 + fi + + # 检查是否已有Clash托盘图标 + if ps -ef | grep -q "[y]ad.*clash"; then + echo -e "\n[INFO] 系统托盘图标已存在,跳过添加" + return 0 + fi + + # 启动系统托盘图标 + nohup yad --notification \ + --image="$icon_path" \ + --text="Clash" \ + --command="xdg-open http://127.0.0.1:9090/ui" \ + --no-middle \ + &> "$Log_Dir/tray.log" & + + echo -e "\n[INFO] 系统托盘图标已启动" +} + # 自定义action函数,实现通用action功能 success() { echo -en "\\033[60G[\\033[1;32m OK \\033[0;39m]\r" @@ -70,7 +143,157 @@ if_success() { fi } +# 检查订阅地址并下载配置文件 +check_and_download_config() { + local clash_url="$1" + local temp_dir="$2" + local conf_dir="$3" + # 将 CLASH_URL 变量的值赋给 URL 变量,并检查 CLASH_URL 是否为空 + local url=${clash_url:?Error: clash_url variable is not set or empty} + + # 检查url是否有效 + echo -e '\n正在检测订阅地址...' + local Text1="Clash订阅地址可访问!" + local Text2="Clash订阅地址不可访问!" + + # 检查URL格式 + if [[ ! $url =~ ^https?:// ]]; then + echo -e "\033[31m[ERROR] 无效的URL格式: $url\033[0m" + echo -e "URL必须以 http:// 或 https:// 开头" + exit 1 + fi + + # 尝试解析域名 + local domain=$(echo "$url" | sed -E 's|^https?://([^/]+).*|\1|') + if ! host "$domain" >/dev/null 2>&1; then + echo -e "\033[31m[ERROR] 无法解析域名: $domain\033[0m" + echo -e "请检查网络连接和DNS设置" + exit 1 + fi + + # 检查URL可访问性 + curl -o /dev/null -L -k -sS --retry 5 -m 10 --connect-timeout 10 -w "%{http_code}" "$url" | grep -E '^[23][0-9]{2}$' &>/dev/null + local ReturnStatus=$? + if_success "$Text1" "$Text2" $ReturnStatus + + # 拉取更新config.yml文件 + echo -e '\n正在下载Clash配置文件...' + local Text3="配置文件config.yaml下载成功!" + local Text4="配置文件config.yaml下载失败,退出启动!" + + # 尝试使用curl进行下载 + curl -L -k -sS --retry 5 -m 10 -o "$temp_dir/clash.yaml" "$url" + ReturnStatus=$? + if [ $ReturnStatus -ne 0 ]; then + echo -e "\033[33m[WARN] curl下载失败,尝试使用wget...\033[0m" + # 如果使用curl下载失败,尝试使用wget进行下载 + for i in {1..10} + do + wget -q --no-check-certificate -O "$temp_dir/clash.yaml" "$url" + ReturnStatus=$? + if [ $ReturnStatus -eq 0 ]; then + break + else + echo -e "\033[33m[WARN] 第 $i 次wget下载尝试失败\033[0m" + sleep 1 + fi + done + fi + if_success "$Text3" "$Text4" $ReturnStatus + + # 检查下载的文件是否存在且非空 + if [ ! -s "$temp_dir/clash.yaml" ]; then + echo -e "\033[31m[ERROR] 下载的配置文件为空或不存在\033[0m" + exit 1 + fi + + # 重命名clash配置文件 + \cp -a "$temp_dir/clash.yaml" "$temp_dir/clash_config.yaml" + + ## 判断订阅内容是否符合clash配置文件标准,尝试转换(当前不支持对 x86_64 以外的CPU架构服务器进行clash配置文件检测和转换,此功能将在后续添加) + if [[ $CpuArch =~ "x86_64" || $CpuArch =~ "amd64" ]]; then + echo -e '\n判断订阅内容是否符合clash配置文件标准:' + bash $Server_Dir/scripts/clash_profile_conversion.sh + sleep 3 + fi + + ## Clash 配置文件重新格式化及配置 + # 取出代理相关配置 + #sed -n '/^proxies:/,$p' $Temp_Dir/clash.yaml > $Temp_Dir/proxy.txt + sed -n '/^proxies:/,$p' $Temp_Dir/clash_config.yaml > $Temp_Dir/proxy.txt + + # 合并形成新的config.yaml + cat $Temp_Dir/templete_config.yaml > $Temp_Dir/config.yaml + cat $Temp_Dir/proxy.txt >> $Temp_Dir/config.yaml + \cp $Temp_Dir/config.yaml $Conf_Dir/ +} + +# 启动Clash服务 +start_clash_service() { + local server_dir="$1" + local conf_dir="$2" + local log_dir="$3" + + echo -e '\n正在启动Clash服务...' + local Text5="服务启动成功!" + local Text6="服务启动失败!" + if [[ $CpuArch =~ "x86_64" || $CpuArch =~ "amd64" ]]; then + nohup $server_dir/bin/clash-linux-amd64 -d $conf_dir &> $log_dir/clash.log & + ReturnStatus=$? + if_success $Text5 $Text6 $ReturnStatus + elif [[ $CpuArch =~ "aarch64" || $CpuArch =~ "arm64" ]]; then + nohup $server_dir/bin/clash-linux-arm64 -d $conf_dir &> $log_dir/clash.log & + ReturnStatus=$? + if_success $Text5 $Text6 $ReturnStatus + elif [[ $CpuArch =~ "armv7" ]]; then + nohup $server_dir/bin/clash-linux-armv7 -d $conf_dir &> $log_dir/clash.log & + ReturnStatus=$? + if_success $Text5 $Text6 $ReturnStatus + else + echo -e "\033[31m\n[ERROR] Unsupported CPU Architecture!\033[0m" + exit 1 + fi +} + +# 配置系统代理环境变量 +setup_proxy_env() { + # 检查是否有root权限 + if [ "$(id -u)" -ne 0 ]; then + echo -e "\033[31m[ERROR] 设置系统代理环境变量需要root权限\033[0m" + echo -e "请使用sudo或以root用户身份运行此脚本" + return 0 + fi + + # 添加环境变量(root权限) + cat>/etc/profile.d/clash.sh</dev/null -curl -o /dev/null -L -k -sS --retry 5 -m 10 --connect-timeout 10 -w "%{http_code}" $URL | grep -E '^[23][0-9]{2}$' &>/dev/null -ReturnStatus=$? -if_success $Text1 $Text2 $ReturnStatus - -# 拉取更新config.yml文件 -echo -e '\n正在下载Clash配置文件...' -Text3="配置文件config.yaml下载成功!" -Text4="配置文件config.yaml下载失败,退出启动!" - -# 尝试使用curl进行下载 -curl -L -k -sS --retry 5 -m 10 -o $Temp_Dir/clash.yaml $URL -ReturnStatus=$? -if [ $ReturnStatus -ne 0 ]; then - # 如果使用curl下载失败,尝试使用wget进行下载 - for i in {1..10} - do - wget -q --no-check-certificate -O $Temp_Dir/clash.yaml $URL - ReturnStatus=$? - if [ $ReturnStatus -eq 0 ]; then - break - else - continue - fi - done +if [ "$SKIP_DOWNLOAD_CONFIG" = false ]; then + check_and_download_config "$CLASH_URL" "$Temp_Dir" "$Conf_Dir" +else + echo -e "\n[INFO] 跳过配置文件下载..." fi -if_success $Text3 $Text4 $ReturnStatus - -# 重命名clash配置文件 -\cp -a $Temp_Dir/clash.yaml $Temp_Dir/clash_config.yaml - - -## 判断订阅内容是否符合clash配置文件标准,尝试转换(当前不支持对 x86_64 以外的CPU架构服务器进行clash配置文件检测和转换,此功能将在后续添加) -if [[ $CpuArch =~ "x86_64" || $CpuArch =~ "amd64" ]]; then - echo -e '\n判断订阅内容是否符合clash配置文件标准:' - bash $Server_Dir/scripts/clash_profile_conversion.sh - sleep 3 -fi - - -## Clash 配置文件重新格式化及配置 -# 取出代理相关配置 -#sed -n '/^proxies:/,$p' $Temp_Dir/clash.yaml > $Temp_Dir/proxy.txt -sed -n '/^proxies:/,$p' $Temp_Dir/clash_config.yaml > $Temp_Dir/proxy.txt - -# 合并形成新的config.yaml -cat $Temp_Dir/templete_config.yaml > $Temp_Dir/config.yaml -cat $Temp_Dir/proxy.txt >> $Temp_Dir/config.yaml -\cp $Temp_Dir/config.yaml $Conf_Dir/ # Configure Clash Dashboard Work_Dir=$(cd $(dirname $0); pwd) @@ -155,59 +328,27 @@ Dashboard_Dir="${Work_Dir}/dashboard/public" sed -ri "s@^# external-ui:.*@external-ui: ${Dashboard_Dir}@g" $Conf_Dir/config.yaml sed -r -i '/^secret: /s@(secret: ).*@\1'${Secret}'@g' $Conf_Dir/config.yaml - -## 启动Clash服务 -echo -e '\n正在启动Clash服务...' -Text5="服务启动成功!" -Text6="服务启动失败!" -if [[ $CpuArch =~ "x86_64" || $CpuArch =~ "amd64" ]]; then - nohup $Server_Dir/bin/clash-linux-amd64 -d $Conf_Dir &> $Log_Dir/clash.log & - ReturnStatus=$? - if_success $Text5 $Text6 $ReturnStatus -elif [[ $CpuArch =~ "aarch64" || $CpuArch =~ "arm64" ]]; then - nohup $Server_Dir/bin/clash-linux-arm64 -d $Conf_Dir &> $Log_Dir/clash.log & - ReturnStatus=$? - if_success $Text5 $Text6 $ReturnStatus -elif [[ $CpuArch =~ "armv7" ]]; then - nohup $Server_Dir/bin/clash-linux-armv7 -d $Conf_Dir &> $Log_Dir/clash.log & - ReturnStatus=$? - if_success $Text5 $Text6 $ReturnStatus -else - echo -e "\033[31m\n[ERROR] Unsupported CPU Architecture!\033[0m" - exit 1 -fi - # Output Dashboard access address and Secret echo '' echo -e "Clash Dashboard 访问地址: http://:9090/ui" echo -e "Secret: ${Secret}" echo '' -# 添加环境变量(root权限) -cat>/etc/profile.d/clash.sh<