mirror of
https://github.com/wnlen/clash-for-linux.git
synced 2026-02-04 10:11:28 +08:00
Update start.sh
This commit is contained in:
137
start.sh
137
start.sh
@ -33,10 +33,24 @@ fi
|
|||||||
#################### 变量设置 ####################
|
#################### 变量设置 ####################
|
||||||
|
|
||||||
Conf_Dir="$Server_Dir/conf"
|
Conf_Dir="$Server_Dir/conf"
|
||||||
Temp_Dir="$Server_Dir/temp"
|
|
||||||
Log_Dir="$Server_Dir/logs"
|
|
||||||
|
|
||||||
mkdir -p "$Conf_Dir" "$Temp_Dir" "$Log_Dir"
|
# systemd + 非 root 运行(clash 用户)时,临时目录与日志目录必须可写
|
||||||
|
if [ "${SYSTEMD_MODE:-false}" = "true" ] && [ "$(id -u)" -ne 0 ]; then
|
||||||
|
Temp_Dir="/tmp/clash-for-linux"
|
||||||
|
Log_Dir="/tmp/clash-for-linux/logs"
|
||||||
|
else
|
||||||
|
Temp_Dir="$Server_Dir/temp"
|
||||||
|
Log_Dir="$Server_Dir/logs"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$Conf_Dir" "$Temp_Dir" "$Log_Dir" || {
|
||||||
|
echo "[ERR] cannot create dirs: Conf_Dir=$Conf_Dir Temp_Dir=$Temp_Dir Log_Dir=$Log_Dir"
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
# 再做一次可写性检查,避免后面玄学 exit
|
||||||
|
touch "$Temp_Dir/.write_test" 2>/dev/null || { echo "[ERR] Temp_Dir not writable: $Temp_Dir"; exit 2; }
|
||||||
|
rm -f "$Temp_Dir/.write_test" 2>/dev/null || true
|
||||||
|
|
||||||
PID_FILE="${CLASH_PID_FILE:-$Temp_Dir/clash.pid}"
|
PID_FILE="${CLASH_PID_FILE:-$Temp_Dir/clash.pid}"
|
||||||
|
|
||||||
@ -314,10 +328,13 @@ fi
|
|||||||
|
|
||||||
#################### 订阅转换/拼接(非兜底路径) ####################
|
#################### 订阅转换/拼接(非兜底路径) ####################
|
||||||
if [ "$SKIP_CONFIG_REBUILD" != "true" ]; then
|
if [ "$SKIP_CONFIG_REBUILD" != "true" ]; then
|
||||||
# 重命名订阅文件
|
# 运行期配置文件:默认用 Temp_Dir(systemd + clash 用户可写)
|
||||||
|
CONFIG_FILE="$Temp_Dir/config.yaml"
|
||||||
|
|
||||||
|
# 1) 重命名订阅文件
|
||||||
\cp -a "$Temp_Dir/clash.yaml" "$Temp_Dir/clash_config.yaml"
|
\cp -a "$Temp_Dir/clash.yaml" "$Temp_Dir/clash_config.yaml"
|
||||||
|
|
||||||
# 判断订阅内容是否符合clash配置文件标准,尝试转换(需 subconverter 可执行文件支持)
|
# 2) 判断订阅内容是否符合 clash 配置文件标准,尝试转换(需 subconverter)
|
||||||
# shellcheck disable=SC1090
|
# shellcheck disable=SC1090
|
||||||
source "$Server_Dir/scripts/resolve_subconverter.sh"
|
source "$Server_Dir/scripts/resolve_subconverter.sh"
|
||||||
|
|
||||||
@ -330,59 +347,70 @@ if [ "$SKIP_CONFIG_REBUILD" != "true" ]; then
|
|||||||
echo -e "\033[33m[WARN]\033[0m 未检测到可用的 subconverter,跳过订阅转换"
|
echo -e "\033[33m[WARN]\033[0m 未检测到可用的 subconverter,跳过订阅转换"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 取出代理相关配置
|
# 3) 取出代理相关配置(从 proxies: 开始)
|
||||||
sed -n '/^proxies:/,$p' "$Temp_Dir/clash_config.yaml" > "$Temp_Dir/proxy.txt"
|
sed -n '/^proxies:/,$p' "$Temp_Dir/clash_config.yaml" > "$Temp_Dir/proxy.txt"
|
||||||
|
|
||||||
# 合并形成新的config.yaml,并替换配置占位符
|
# 4) 合并形成新的 config,并替换配置占位符
|
||||||
cat "$Temp_Dir/templete_config.yaml" > "$Temp_Dir/config.yaml"
|
cat "$Temp_Dir/templete_config.yaml" > "$CONFIG_FILE"
|
||||||
cat "$Temp_Dir/proxy.txt" >> "$Temp_Dir/config.yaml"
|
cat "$Temp_Dir/proxy.txt" >> "$CONFIG_FILE"
|
||||||
|
|
||||||
# 替换配置文件中的占位符为环境变量值
|
sed -i "s/CLASH_HTTP_PORT_PLACEHOLDER/${CLASH_HTTP_PORT}/g" "$CONFIG_FILE"
|
||||||
sed -i "s/CLASH_HTTP_PORT_PLACEHOLDER/${CLASH_HTTP_PORT}/g" "$Temp_Dir/config.yaml"
|
sed -i "s/CLASH_SOCKS_PORT_PLACEHOLDER/${CLASH_SOCKS_PORT}/g" "$CONFIG_FILE"
|
||||||
sed -i "s/CLASH_SOCKS_PORT_PLACEHOLDER/${CLASH_SOCKS_PORT}/g" "$Temp_Dir/config.yaml"
|
sed -i "s/CLASH_REDIR_PORT_PLACEHOLDER/${CLASH_REDIR_PORT}/g" "$CONFIG_FILE"
|
||||||
sed -i "s/CLASH_REDIR_PORT_PLACEHOLDER/${CLASH_REDIR_PORT}/g" "$Temp_Dir/config.yaml"
|
sed -i "s/CLASH_LISTEN_IP_PLACEHOLDER/${CLASH_LISTEN_IP}/g" "$CONFIG_FILE"
|
||||||
sed -i "s/CLASH_LISTEN_IP_PLACEHOLDER/${CLASH_LISTEN_IP}/g" "$Temp_Dir/config.yaml"
|
sed -i "s/CLASH_ALLOW_LAN_PLACEHOLDER/${CLASH_ALLOW_LAN}/g" "$CONFIG_FILE"
|
||||||
sed -i "s/CLASH_ALLOW_LAN_PLACEHOLDER/${CLASH_ALLOW_LAN}/g" "$Temp_Dir/config.yaml"
|
|
||||||
|
|
||||||
# 配置 external-controller
|
# 5) 配置 external-controller
|
||||||
if [ "$EXTERNAL_CONTROLLER_ENABLED" = "true" ]; then
|
if [ "$EXTERNAL_CONTROLLER_ENABLED" = "true" ]; then
|
||||||
sed -i "s/EXTERNAL_CONTROLLER_PLACEHOLDER/${EXTERNAL_CONTROLLER}/g" "$Temp_Dir/config.yaml"
|
sed -i "s/EXTERNAL_CONTROLLER_PLACEHOLDER/${EXTERNAL_CONTROLLER}/g" "$CONFIG_FILE"
|
||||||
else
|
else
|
||||||
sed -i "s/external-controller: 'EXTERNAL_CONTROLLER_PLACEHOLDER'/# external-controller: disabled/g" "$Temp_Dir/config.yaml"
|
sed -i "s/external-controller: 'EXTERNAL_CONTROLLER_PLACEHOLDER'/# external-controller: disabled/g" "$CONFIG_FILE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
apply_tun_config "$Temp_Dir/config.yaml"
|
apply_tun_config "$CONFIG_FILE"
|
||||||
apply_mixin_config "$Temp_Dir/config.yaml" "$Server_Dir"
|
apply_mixin_config "$CONFIG_FILE" "$Server_Dir"
|
||||||
|
|
||||||
\cp "$Temp_Dir/config.yaml" "$Conf_Dir/"
|
# 6) 是否同步到 conf(root/非 systemd 时才做;systemd+非root跳过)
|
||||||
|
if [ "${SYSTEMD_MODE:-false}" = "true" ] && [ "$(id -u)" -ne 0 ]; then
|
||||||
|
echo "[WARN] systemd(non-root): skip copying config to $Conf_Dir"
|
||||||
|
else
|
||||||
|
\cp "$CONFIG_FILE" "$Conf_Dir/"
|
||||||
|
fi
|
||||||
|
|
||||||
# Configure Clash Dashboard
|
# 7) Dashboard external-ui(systemd+非root:把 ui 放 Temp_Dir 下,避免写 conf)
|
||||||
Work_Dir="$(cd "$(dirname "$0")" && pwd)"
|
Work_Dir="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
# SAFE_PATHS: only allow paths under $Conf_Dir, so place dashboard under conf via symlink
|
|
||||||
Dashboard_Src="${Work_Dir}/dashboard/public"
|
Dashboard_Src="${Work_Dir}/dashboard/public"
|
||||||
Dashboard_Link="${Conf_Dir}/ui"
|
|
||||||
|
|
||||||
if [ "$EXTERNAL_CONTROLLER_ENABLED" = "true" ]; then
|
if [ "$EXTERNAL_CONTROLLER_ENABLED" = "true" ]; then
|
||||||
# create/update symlink
|
if [ "${SYSTEMD_MODE:-false}" = "true" ] && [ "$(id -u)" -ne 0 ]; then
|
||||||
|
# runtime ui path (writable)
|
||||||
|
Dashboard_Link="$Temp_Dir/ui"
|
||||||
if [ -d "$Dashboard_Src" ]; then
|
if [ -d "$Dashboard_Src" ]; then
|
||||||
ln -sfn "$Dashboard_Src" "$Dashboard_Link"
|
ln -sfn "$Dashboard_Src" "$Dashboard_Link" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# conf ui path (root can manage)
|
||||||
|
Dashboard_Link="${Conf_Dir}/ui"
|
||||||
|
if [ -d "$Dashboard_Src" ]; then
|
||||||
|
ln -sfn "$Dashboard_Src" "$Dashboard_Link" || true
|
||||||
else
|
else
|
||||||
echo -e "\033[33m[WARN]\033[0m Dashboard source not found: $Dashboard_Src (external-ui may not work)"
|
echo -e "\033[33m[WARN]\033[0m Dashboard source not found: $Dashboard_Src (external-ui may not work)"
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# ensure external-ui points to conf subpath
|
# ensure external-ui points to Dashboard_Link
|
||||||
if grep -qE '^[[:space:]]*external-ui:' "$Conf_Dir/config.yaml"; then
|
if grep -qE '^[[:space:]]*external-ui:' "$CONFIG_FILE"; then
|
||||||
sed -i -E "s|^[[:space:]]*external-ui:.*$|external-ui: ${Dashboard_Link}|g" "$Conf_Dir/config.yaml"
|
sed -i -E "s|^[[:space:]]*external-ui:.*$|external-ui: ${Dashboard_Link}|g" "$CONFIG_FILE"
|
||||||
else
|
else
|
||||||
printf "\nexternal-ui: %s\n" "$Dashboard_Link" >> "$Conf_Dir/config.yaml"
|
printf "\nexternal-ui: %s\n" "$Dashboard_Link" >> "$CONFIG_FILE"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 写入 secret
|
# 8) 写入 secret(写到 runtime config)
|
||||||
force_write_secret "$Conf_Dir/config.yaml"
|
force_write_secret "$CONFIG_FILE"
|
||||||
|
|
||||||
else
|
else
|
||||||
# 兜底路径:尽量也写入 secret(若 config 里有 secret: 行就替换;没有就追加)
|
# 兜底路径:尽量也写入 secret(conf/config.yaml 可写时)
|
||||||
if grep -qE '^secret:\s*' "$Conf_Dir/config.yaml" 2>/dev/null; then
|
if grep -qE '^secret:\s*' "$Conf_Dir/config.yaml" 2>/dev/null; then
|
||||||
force_write_secret "$Conf_Dir/config.yaml"
|
force_write_secret "$Conf_Dir/config.yaml"
|
||||||
else
|
else
|
||||||
@ -392,18 +420,37 @@ fi
|
|||||||
|
|
||||||
#################### 启动Clash服务 ####################
|
#################### 启动Clash服务 ####################
|
||||||
|
|
||||||
# 启动前确保 config.yaml 存在且非空
|
# 选择运行期配置文件与工作目录
|
||||||
if [ ! -s "$Conf_Dir/config.yaml" ]; then
|
# - systemd + 非 root(通常 User=clash):用 Temp_Dir 下的运行态配置,工作目录也用 Temp_Dir(可写)
|
||||||
echo -e "\033[31m[ERROR]\033[0m conf/config.yaml 不存在或为空,无法启动 Clash" >&2
|
# - 其他情况:用 Conf_Dir/config.yaml,工作目录用 Conf_Dir
|
||||||
exit 1
|
if [ "${SYSTEMD_MODE:-false}" = "true" ] && [ "$(id -u)" -ne 0 ]; then
|
||||||
|
CONFIG_FILE="${CONFIG_FILE:-$Temp_Dir/config.yaml}"
|
||||||
|
RUNTIME_DIR="${Temp_Dir}"
|
||||||
|
else
|
||||||
|
CONFIG_FILE="${CONFIG_FILE:-$Conf_Dir/config.yaml}"
|
||||||
|
RUNTIME_DIR="${Conf_Dir}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 启动前确保配置文件存在且非空
|
||||||
|
if [ ! -s "$CONFIG_FILE" ]; then
|
||||||
|
echo -e "\033[31m[ERROR]\033[0m config 不存在或为空:$CONFIG_FILE,无法启动 Clash" >&2
|
||||||
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 最终护栏:禁止未渲染的占位符进入运行态
|
# 最终护栏:禁止未渲染的占位符进入运行态
|
||||||
if grep -q '\${' "$Conf_Dir/config.yaml"; then
|
if grep -q '\${' "$CONFIG_FILE"; then
|
||||||
echo "[ERROR] config.yaml contains unresolved placeholders (\${...}). Please check template rendering." >&2
|
echo "[ERROR] config contains unresolved placeholders (\${...}): $CONFIG_FILE" >&2
|
||||||
exit 1
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 确保运行目录存在且可写(clash/mihomo 可能会写 cache/geo 数据)
|
||||||
|
mkdir -p "$RUNTIME_DIR" 2>/dev/null || true
|
||||||
|
touch "$RUNTIME_DIR/.write_test" 2>/dev/null || {
|
||||||
|
echo "[ERROR] runtime dir not writable: $RUNTIME_DIR (uid=$(id -u))" >&2
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
rm -f "$RUNTIME_DIR/.write_test" 2>/dev/null || true
|
||||||
|
|
||||||
echo -e '\n正在启动Clash服务...'
|
echo -e '\n正在启动Clash服务...'
|
||||||
Text5="服务启动成功!"
|
Text5="服务启动成功!"
|
||||||
Text6="服务启动失败!"
|
Text6="服务启动失败!"
|
||||||
@ -414,11 +461,15 @@ ReturnStatus=$?
|
|||||||
if [ "$ReturnStatus" -eq 0 ]; then
|
if [ "$ReturnStatus" -eq 0 ]; then
|
||||||
if [ "${SYSTEMD_MODE:-false}" = "true" ]; then
|
if [ "${SYSTEMD_MODE:-false}" = "true" ]; then
|
||||||
echo "[INFO] SYSTEMD_MODE=true,前台启动交给 systemd 监管"
|
echo "[INFO] SYSTEMD_MODE=true,前台启动交给 systemd 监管"
|
||||||
|
echo "[INFO] Using config: $CONFIG_FILE"
|
||||||
|
echo "[INFO] Using runtime dir: $RUNTIME_DIR"
|
||||||
# systemd 前台:让 systemd 直接跟踪 clash 进程
|
# systemd 前台:让 systemd 直接跟踪 clash 进程
|
||||||
exec "$Clash_Bin" -d "$Conf_Dir"
|
exec "$Clash_Bin" -d "$RUNTIME_DIR" -f "$CONFIG_FILE"
|
||||||
else
|
else
|
||||||
echo "[INFO] 后台启动 (nohup)"
|
echo "[INFO] 后台启动 (nohup)"
|
||||||
nohup "$Clash_Bin" -d "$Conf_Dir" >>"$Log_Dir/clash.log" 2>&1 &
|
echo "[INFO] Using config: $CONFIG_FILE"
|
||||||
|
echo "[INFO] Using runtime dir: $RUNTIME_DIR"
|
||||||
|
nohup "$Clash_Bin" -d "$RUNTIME_DIR" -f "$CONFIG_FILE" >>"$Log_Dir/clash.log" 2>&1 &
|
||||||
PID=$!
|
PID=$!
|
||||||
ReturnStatus=$?
|
ReturnStatus=$?
|
||||||
if [ "$ReturnStatus" -eq 0 ]; then
|
if [ "$ReturnStatus" -eq 0 ]; then
|
||||||
|
|||||||
Reference in New Issue
Block a user