mirror of
https://github.com/wnlen/clash-for-linux.git
synced 2026-03-21 22:06:45 +08:00
rectification
This commit is contained in:
129
clashctl
129
clashctl
@ -263,6 +263,13 @@ cmd_update() {
|
||||
|
||||
cmd_status() {
|
||||
local mode running="no"
|
||||
local service_active="" service_enabled=""
|
||||
local pid=""
|
||||
local controller dashboard_url
|
||||
local config_source generate_status generate_reason generate_at
|
||||
local run_status run_mode run_pid run_at
|
||||
local http_port dashboard_port
|
||||
local secret_exists="no"
|
||||
|
||||
mode="$(detect_mode)"
|
||||
|
||||
@ -271,46 +278,132 @@ cmd_status() {
|
||||
if systemctl is-active --quiet "$SERVICE_NAME"; then
|
||||
running="yes"
|
||||
fi
|
||||
service_active="$(systemctl is-active "$SERVICE_NAME" 2>/dev/null || true)"
|
||||
service_enabled="$(systemctl is-enabled "$SERVICE_NAME" 2>/dev/null || true)"
|
||||
;;
|
||||
systemd-installed)
|
||||
running="no"
|
||||
service_active="$(systemctl is-active "$SERVICE_NAME" 2>/dev/null || true)"
|
||||
service_enabled="$(systemctl is-enabled "$SERVICE_NAME" 2>/dev/null || true)"
|
||||
;;
|
||||
script)
|
||||
if is_script_running; then
|
||||
running="yes"
|
||||
fi
|
||||
pid="$(read_pid 2>/dev/null || true)"
|
||||
;;
|
||||
none)
|
||||
running="no"
|
||||
;;
|
||||
esac
|
||||
|
||||
generate_status="$(read_state_value LAST_GENERATE_STATUS || true)"
|
||||
generate_reason="$(read_state_value LAST_GENERATE_REASON || true)"
|
||||
config_source="$(read_state_value LAST_CONFIG_SOURCE || true)"
|
||||
generate_at="$(read_state_value LAST_GENERATE_AT || true)"
|
||||
|
||||
run_status="$(read_state_value LAST_RUN_STATUS || true)"
|
||||
run_mode="$(read_state_value LAST_RUN_MODE || true)"
|
||||
run_pid="$(read_state_value LAST_RUN_PID || true)"
|
||||
run_at="$(read_state_value LAST_RUN_AT || true)"
|
||||
|
||||
controller="$(read_runtime_config_value "external-controller" || true)"
|
||||
dashboard_url="$(cmd_ui --raw 2>/dev/null || true)"
|
||||
http_port="$(http_port_from_config)"
|
||||
dashboard_port="$(port_from_controller)"
|
||||
|
||||
if [ -n "$(read_runtime_config_value "secret" || true)" ]; then
|
||||
secret_exists="yes"
|
||||
fi
|
||||
|
||||
echo "=== Clash Status ==="
|
||||
echo "Project : $PROJECT_DIR"
|
||||
echo "Mode : $mode"
|
||||
echo "Running : $running"
|
||||
echo "Config : $RUNTIME_CONFIG"
|
||||
|
||||
if [ "$mode" = "systemd" ] && service_unit_exists; then
|
||||
echo "Service : installed"
|
||||
echo "Active : $(systemctl is-active "$SERVICE_NAME" 2>/dev/null || true)"
|
||||
echo "Enabled : $(systemctl is-enabled "$SERVICE_NAME" 2>/dev/null || true)"
|
||||
fi
|
||||
|
||||
if [ "$mode" = "script" ]; then
|
||||
local pid
|
||||
pid="$(read_pid 2>/dev/null || true)"
|
||||
echo "PID : ${pid:-unknown}"
|
||||
if [ -f "$RUNTIME_CONFIG" ]; then
|
||||
echo "ConfigExists : yes"
|
||||
else
|
||||
echo "ConfigExists : no"
|
||||
fi
|
||||
|
||||
if [ -f "$STATE_FILE" ]; then
|
||||
echo "LastStatus : $(read_state_value LAST_GENERATE_STATUS || true)"
|
||||
echo "LastReason : $(read_state_value LAST_GENERATE_REASON || true)"
|
||||
echo "LastSource : $(read_state_value LAST_CONFIG_SOURCE || true)"
|
||||
echo "LastAt : $(read_state_value LAST_GENERATE_AT || true)"
|
||||
echo "StateFile : $STATE_FILE"
|
||||
else
|
||||
echo "StateFile : missing"
|
||||
fi
|
||||
|
||||
local controller
|
||||
controller="$(read_runtime_config_value "external-controller" || true)"
|
||||
if [ -n "${controller:-}" ]; then
|
||||
echo "Dashboard : $(cmd_ui --raw)"
|
||||
case "$mode" in
|
||||
systemd|systemd-installed)
|
||||
echo "Service : installed"
|
||||
echo "Active : ${service_active:-unknown}"
|
||||
echo "Enabled : ${service_enabled:-unknown}"
|
||||
;;
|
||||
script)
|
||||
echo "Service : script"
|
||||
echo "PID : ${pid:-unknown}"
|
||||
;;
|
||||
none)
|
||||
echo "Service : none"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Generate : ${generate_status:-unknown}"
|
||||
if [ -n "${generate_reason:-}" ]; then
|
||||
echo "GenReason : $generate_reason"
|
||||
fi
|
||||
if [ -n "${config_source:-}" ]; then
|
||||
echo "ConfigSource : $config_source"
|
||||
fi
|
||||
if [ -n "${generate_at:-}" ]; then
|
||||
echo "GeneratedAt : $generate_at"
|
||||
fi
|
||||
|
||||
if [ -n "${run_status:-}" ]; then
|
||||
echo "RunStatus : $run_status"
|
||||
fi
|
||||
if [ -n "${run_mode:-}" ]; then
|
||||
echo "RunMode : $run_mode"
|
||||
fi
|
||||
if [ -n "${run_pid:-}" ]; then
|
||||
echo "RunPID : $run_pid"
|
||||
fi
|
||||
if [ -n "${run_at:-}" ]; then
|
||||
echo "RunAt : $run_at"
|
||||
fi
|
||||
|
||||
echo "ProxyPort : $http_port"
|
||||
echo "DashPort : $dashboard_port"
|
||||
|
||||
if [ -n "${controller:-}" ]; then
|
||||
echo "Controller : $controller"
|
||||
else
|
||||
echo "Controller : 127.0.0.1:9090 (fallback)"
|
||||
fi
|
||||
|
||||
if [ -n "${dashboard_url:-}" ]; then
|
||||
echo "Dashboard : $dashboard_url"
|
||||
fi
|
||||
|
||||
echo "Secret : $secret_exists"
|
||||
|
||||
echo
|
||||
case "$running" in
|
||||
yes)
|
||||
ok "status summary: running"
|
||||
;;
|
||||
no)
|
||||
if [ "$mode" = "systemd-installed" ]; then
|
||||
warn "status summary: installed but not running"
|
||||
else
|
||||
warn "status summary: not running"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
warn "status summary: unknown"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
doctor_ok() {
|
||||
|
||||
BIN
config/Country.mmdb
Normal file
BIN
config/Country.mmdb
Normal file
Binary file not shown.
9
config/mixin.d/README.md
Normal file
9
config/mixin.d/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Mixin 配置目录
|
||||
|
||||
将额外的 Clash YAML 配置放在此目录下,脚本会按文件名排序后依次拼接到生成的 `config.yaml` 末尾。
|
||||
|
||||
如需手动指定顺序或使用自定义路径,请在 `.env` 中设置:
|
||||
|
||||
```bash
|
||||
export CLASH_MIXIN_PATHS='conf/mixin.d/base.yaml,conf/mixin.d/rules.yaml'
|
||||
```
|
||||
31
config/templete.yaml
Normal file
31
config/templete.yaml
Normal file
@ -0,0 +1,31 @@
|
||||
# HTTP 代理端口
|
||||
port: CLASH_HTTP_PORT_PLACEHOLDER
|
||||
|
||||
# SOCKS5 代理端口
|
||||
socks-port: CLASH_SOCKS_PORT_PLACEHOLDER
|
||||
|
||||
# Linux 和 macOS 的 redir 代理端口
|
||||
redir-port: CLASH_REDIR_PORT_PLACEHOLDER
|
||||
|
||||
# 监听IP地址
|
||||
bind-address: CLASH_LISTEN_IP_PLACEHOLDER
|
||||
|
||||
# 允许局域网的连接
|
||||
allow-lan: CLASH_ALLOW_LAN_PLACEHOLDER
|
||||
|
||||
# 规则模式:Rule(规则) / Global(全局代理)/ Direct(全局直连)
|
||||
mode: rule
|
||||
|
||||
# 设置日志输出级别 (默认级别:silent,即不输出任何内容,以避免因日志内容过大而导致程序内存溢出)。
|
||||
# 5 个级别:silent / info / warning / error / debug。级别越高日志输出量越大,越倾向于调试,若需要请自行开启。
|
||||
log-level: silent
|
||||
# Clash 的 RESTful API
|
||||
external-controller: 'EXTERNAL_CONTROLLER_PLACEHOLDER'
|
||||
|
||||
# RESTful API 的口令
|
||||
secret: 'b&ZlKTte5OnEt2Sn'
|
||||
|
||||
# 您可以将静态网页资源(如 clash-dashboard)放置在一个目录中,clash 将会服务于 `RESTful API/ui`
|
||||
# 参数应填写配置目录的相对路径或绝对路径。
|
||||
# external-ui: /code/clash-dashboard
|
||||
|
||||
106
install.sh
106
install.sh
@ -470,7 +470,10 @@ if [ -f "$Install_Dir/clashoff" ]; then
|
||||
fi
|
||||
|
||||
# =========================
|
||||
# 友好收尾输出(闭环)
|
||||
# 友好收尾输出
|
||||
# - 不再强调瞬时 active / inactive
|
||||
# - 统一引导到 clashctl
|
||||
# - 兼容 systemd / 非 systemd
|
||||
# =========================
|
||||
|
||||
section "安装完成"
|
||||
@ -478,28 +481,37 @@ ok "Clash for Linux 已安装至: $(path "${Install_Dir}")"
|
||||
|
||||
log "📦 安装目录:$(path "${Install_Dir}")"
|
||||
log "👤 运行用户:${Service_User}:${Service_Group}"
|
||||
log "🔧 服务名称:${Service_Name}.service"
|
||||
log "🧩 管理入口:$(cmd "clashctl")"
|
||||
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
section "服务状态"
|
||||
|
||||
se="${Service_Enabled:-unknown}"
|
||||
ss="${Service_Started:-unknown}"
|
||||
|
||||
[[ "$se" == "enabled" ]] && se_colored="$(good "$se")" || se_colored="$(bad "$se")"
|
||||
[[ "$ss" == "active" ]] && ss_colored="$(good "$ss")" || ss_colored="$(bad "$ss")"
|
||||
|
||||
log "🧷 开机自启:${se_colored}"
|
||||
log "🟢 服务状态:${ss_colored}"
|
||||
|
||||
log ""
|
||||
log "${C_BOLD}常用命令:${C_NC}"
|
||||
log " $(cmd "systemctl status ${Service_Name}.service")"
|
||||
log " $(cmd "systemctl restart ${Service_Name}.service")"
|
||||
log "🔧 服务名称:${Service_Name}.service"
|
||||
else
|
||||
log "🔧 运行模式:非 systemd 环境(将使用脚本模式兜底)"
|
||||
fi
|
||||
|
||||
# =========================
|
||||
# Dashboard / Secret
|
||||
# 安装结果
|
||||
# 不在这里渲染瞬时运行态,避免误导
|
||||
# =========================
|
||||
section "安装结果"
|
||||
|
||||
ok "核心文件已就位"
|
||||
ok "运行入口已收敛为 clashctl"
|
||||
|
||||
if [[ -x "/usr/local/bin/clashctl" ]]; then
|
||||
ok "命令已可用:$(cmd "clashctl")"
|
||||
else
|
||||
warn "未检测到 /usr/local/bin/clashctl,请确认安装脚本是否已完成链接"
|
||||
fi
|
||||
|
||||
log ""
|
||||
log "${C_BOLD}推荐下一步:${C_NC}"
|
||||
log " 1. $(cmd "clashctl generate") # 生成运行配置"
|
||||
log " 2. $(cmd "clashctl start") # 启动 Clash"
|
||||
log " 3. $(cmd "clashctl doctor") # 健康检查"
|
||||
|
||||
# =========================
|
||||
# 控制面板 / Secret
|
||||
# =========================
|
||||
section "控制面板"
|
||||
|
||||
@ -534,16 +546,24 @@ fi
|
||||
|
||||
CONF_DIR="$Install_Dir/conf"
|
||||
TEMP_DIR="$Install_Dir/temp"
|
||||
RUNTIME_DIR="$Install_Dir/runtime"
|
||||
|
||||
SECRET_VAL=""
|
||||
SECRET_FILE=""
|
||||
|
||||
read_secret_safe() {
|
||||
local f="$1"
|
||||
[[ -f "$f" ]] || return 1
|
||||
read_secret_from_config "$f" 2>/dev/null || true
|
||||
}
|
||||
|
||||
for _ in {1..15}; do
|
||||
for f in \
|
||||
"$RUNTIME_DIR/config.yaml" \
|
||||
"$TEMP_DIR/config.yaml" \
|
||||
"$CONF_DIR/config.yaml"
|
||||
do
|
||||
SECRET_VAL="$(read_secret_from_config "$f" 2>/dev/null || true)"
|
||||
SECRET_VAL="$(read_secret_safe "$f")"
|
||||
if [[ -n "$SECRET_VAL" ]]; then
|
||||
SECRET_FILE="$f"
|
||||
break 2
|
||||
@ -555,16 +575,14 @@ done
|
||||
dash="http://${api_host}:${api_port}/ui"
|
||||
log "🌐 Dashboard:$(url "$dash")"
|
||||
|
||||
SHOW_FILE="${SECRET_FILE:-$CONF_DIR/config.yaml}"
|
||||
SHOW_FILE="${SECRET_FILE:-$RUNTIME_DIR/config.yaml}"
|
||||
|
||||
if [[ -n "$SECRET_VAL" ]]; then
|
||||
MASKED="${SECRET_VAL}"
|
||||
log "🔐 Secret:${C_YELLOW}${MASKED}${C_NC}"
|
||||
# log " 查看完整 Secret:$(cmd "sed -nE 's/^[[:space:]]*secret:[[:space:]]*//p' \"$SHOW_FILE\" | head -n 1")"
|
||||
log "🔐 Secret:${C_YELLOW}${SECRET_VAL}${C_NC}"
|
||||
else
|
||||
log "🔐 Secret:${C_YELLOW}启动中暂未读到(稍后再试)${C_NC}"
|
||||
log " 稍后查看:$(cmd "sed -nE 's/^[[:space:]]*secret:[[:space:]]*//p' \"$CONF_DIR/config.yaml\" | head -n 1")"
|
||||
log " 也可检查运行态:$(cmd "sed -nE 's/^[[:space:]]*secret:[[:space:]]*//p' \"$TEMP_DIR/config.yaml\" | head -n 1")"
|
||||
log "🔐 Secret:${C_YELLOW}暂未读取到${C_NC}"
|
||||
log " 启动后可查看:$(cmd "sed -nE 's/^[[:space:]]*secret:[[:space:]]*//p' \"$RUNTIME_DIR/config.yaml\" | head -n 1")"
|
||||
log " 或检查旧路径:$(cmd "sed -nE 's/^[[:space:]]*secret:[[:space:]]*//p' \"$TEMP_DIR/config.yaml\" | head -n 1")"
|
||||
fi
|
||||
|
||||
# =========================
|
||||
@ -580,20 +598,41 @@ else
|
||||
warn "订阅地址未配置(必须)"
|
||||
log ""
|
||||
log "配置订阅地址:"
|
||||
log " $(cmd "bash -c 'echo \"CLASH_URL=<订阅地址>\" > ${ENV_FILE}'")"
|
||||
log " $(cmd "bash -c 'printf \"%s\n\" \"CLASH_URL=<订阅地址>\" > \"${ENV_FILE}\"'")"
|
||||
log ""
|
||||
log "配置完成后重启服务:"
|
||||
log " $(cmd "systemctl restart ${Service_Name}.service")"
|
||||
log "配置完成后执行:"
|
||||
log " 1. $(cmd "clashctl generate")"
|
||||
log " 2. $(cmd "clashctl start")"
|
||||
log " 3. $(cmd "clashctl doctor")"
|
||||
fi
|
||||
|
||||
# =========================
|
||||
# 下一步
|
||||
# 常用命令(统一只教 clashctl)
|
||||
# =========================
|
||||
section "下一步开启代理(可选)"
|
||||
section "常用命令"
|
||||
|
||||
log " $(cmd "clashctl status") # 查看运行状态"
|
||||
log " $(cmd "clashctl logs") # 查看最近日志"
|
||||
log " $(cmd "clashctl logs -f") # 持续追踪日志"
|
||||
log " $(cmd "clashctl stop") # 停止 Clash"
|
||||
log " $(cmd "clashctl restart") # 重启 Clash"
|
||||
log " $(cmd "clashctl doctor") # 健康检查"
|
||||
|
||||
# =========================
|
||||
# 终端代理(可选)
|
||||
# =========================
|
||||
section "终端代理(可选)"
|
||||
|
||||
log " $(cmd "clashctl on") # 开启当前终端代理"
|
||||
log " $(cmd "clashctl off") # 关闭当前终端代理"
|
||||
log " $(cmd "clashctl status") # 查看状态"
|
||||
|
||||
# =========================
|
||||
# 旧入口收敛提示
|
||||
# =========================
|
||||
section "说明"
|
||||
|
||||
log "旧脚本已收敛,请优先使用:$(cmd "clashctl")"
|
||||
log "不建议继续直接操作 restart.sh / update.sh / 手写 systemctl 命令"
|
||||
|
||||
# =========================
|
||||
# 启动后快速诊断
|
||||
@ -602,6 +641,7 @@ sleep 1
|
||||
if command -v journalctl >/dev/null 2>&1; then
|
||||
if journalctl -u "${Service_Name}.service" -n 50 --no-pager 2>/dev/null \
|
||||
| grep -q "Clash订阅地址不可访问"; then
|
||||
warn "服务启动异常:订阅不可用,请检查 CLASH_URL(可能过期 / 404 / 被墙)。"
|
||||
warn "检测到启动异常:订阅不可用,请检查 CLASH_URL(可能过期 / 404 / 被墙)"
|
||||
log "建议执行:$(cmd "clashctl doctor")"
|
||||
fi
|
||||
fi
|
||||
0
logs/clash.log
Normal file
0
logs/clash.log
Normal file
0
runtime/clash.pid
Normal file
0
runtime/clash.pid
Normal file
0
runtime/proxy.env
Normal file
0
runtime/proxy.env
Normal file
0
runtime/state.env
Normal file
0
runtime/state.env
Normal file
0
scripts/doctor.sh
Normal file
0
scripts/doctor.sh
Normal file
0
scripts/logs.sh
Normal file
0
scripts/logs.sh
Normal file
Reference in New Issue
Block a user