286 lines
8.1 KiB
Bash
286 lines
8.1 KiB
Bash
# shellcheck disable=SC2148
|
|
# shellcheck disable=SC2155
|
|
|
|
function clashon() {
|
|
_get_proxy_port
|
|
systemctl is-active "$BIN_KERNEL_NAME" >&/dev/null || {
|
|
sudo systemctl start "$BIN_KERNEL_NAME" >/dev/null || {
|
|
_failcat '启动失败: 执行 clashstatus 查看日志'
|
|
return 1
|
|
}
|
|
}
|
|
|
|
local auth=$(sudo "$BIN_YQ" '.authentication[0] // ""' "$CLASH_CONFIG_RUNTIME")
|
|
[ -n "$auth" ] && auth=$auth@
|
|
|
|
local http_proxy_addr="http://${auth}127.0.0.1:${MIXED_PORT}"
|
|
local socks_proxy_addr="socks5h://${auth}127.0.0.1:${MIXED_PORT}"
|
|
local no_proxy_addr="localhost,127.0.0.1,::1"
|
|
|
|
export http_proxy=$http_proxy_addr
|
|
export https_proxy=$http_proxy
|
|
export HTTP_PROXY=$http_proxy
|
|
export HTTPS_PROXY=$http_proxy
|
|
|
|
export all_proxy=$socks_proxy_addr
|
|
export ALL_PROXY=$all_proxy
|
|
|
|
export no_proxy=$no_proxy_addr
|
|
export NO_PROXY=$no_proxy
|
|
|
|
_okcat '已开启代理环境'
|
|
}
|
|
|
|
watch_proxy() {
|
|
[ -z "$http_proxy" ] && [[ $- == *i* ]] && {
|
|
_is_root || _failcat '未检测到代理变量,可执行 clashon 开启代理环境' && clashon
|
|
}
|
|
}
|
|
|
|
function clashoff() {
|
|
sudo systemctl stop "$BIN_KERNEL_NAME" && _okcat '已关闭代理环境' ||
|
|
_failcat '关闭失败: 执行 "clashstatus" 查看日志' || return 1
|
|
|
|
unset http_proxy
|
|
unset https_proxy
|
|
unset HTTP_PROXY
|
|
unset HTTPS_PROXY
|
|
unset all_proxy
|
|
unset ALL_PROXY
|
|
unset no_proxy
|
|
unset NO_PROXY
|
|
}
|
|
|
|
clashrestart() {
|
|
{ clashoff && clashon; } >&/dev/null
|
|
}
|
|
|
|
function clashstatus() {
|
|
sudo systemctl status "$BIN_KERNEL_NAME" "$@"
|
|
}
|
|
|
|
function clashui() {
|
|
_get_ui_port
|
|
# 公网ip
|
|
# ifconfig.me
|
|
local query_url='api64.ipify.org'
|
|
local public_ip=$(curl -s --noproxy "*" --connect-timeout 2 $query_url)
|
|
local public_address="http://${public_ip:-公网}:${UI_PORT}/ui"
|
|
# 内网ip
|
|
# ip route get 1.1.1.1 | grep -oP 'src \K\S+'
|
|
local local_ip=$(hostname -I | awk '{print $1}')
|
|
local local_address="http://${local_ip}:${UI_PORT}/ui"
|
|
printf "\n"
|
|
printf "╔═══════════════════════════════════════════════╗\n"
|
|
printf "║ %s ║\n" "$(_okcat 'Web 控制台')"
|
|
printf "║═══════════════════════════════════════════════║\n"
|
|
printf "║ ║\n"
|
|
printf "║ 🔓 注意放行端口:%-5s ║\n" "$UI_PORT"
|
|
printf "║ 🏠 内网:%-31s ║\n" "$local_address"
|
|
printf "║ 🌏 公网:%-31s ║\n" "$public_address"
|
|
printf "║ ☁️ 公共:%-31s ║\n" "$URL_CLASH_UI"
|
|
printf "║ ║\n"
|
|
printf "╚═══════════════════════════════════════════════╝\n"
|
|
printf "\n"
|
|
}
|
|
|
|
_merge_config_restart() {
|
|
local backup="/tmp/rt.backup"
|
|
sudo cat "$CLASH_CONFIG_RUNTIME" 2>/dev/null | sudo tee $backup >&/dev/null
|
|
sudo "$BIN_YQ" eval-all '. as $item ireduce ({}; . *+ $item)' "$CLASH_CONFIG_MIXIN" "$CLASH_CONFIG_RAW" | sudo tee "$CLASH_CONFIG_RUNTIME" >&/dev/null
|
|
_valid_config "$CLASH_CONFIG_RUNTIME" || {
|
|
sudo cat $backup | sudo tee "$CLASH_CONFIG_RUNTIME" >&/dev/null
|
|
_error_quit "验证失败:请检查 Mixin 配置"
|
|
}
|
|
clashrestart
|
|
}
|
|
|
|
function clashsecret() {
|
|
case "$#" in
|
|
0)
|
|
_okcat "当前密钥:$(sudo "$BIN_YQ" '.secret // ""' "$CLASH_CONFIG_RUNTIME")"
|
|
;;
|
|
1)
|
|
sudo "$BIN_YQ" -i ".secret = \"$1\"" "$CLASH_CONFIG_MIXIN" || {
|
|
_failcat "密钥更新失败,请重新输入"
|
|
return 1
|
|
}
|
|
_merge_config_restart
|
|
_okcat "密钥更新成功,已重启生效"
|
|
;;
|
|
*)
|
|
_failcat "密钥不要包含空格或使用引号包围"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
_tunstatus() {
|
|
local tun_status=$(sudo "$BIN_YQ" '.tun.enable' "${CLASH_CONFIG_RUNTIME}")
|
|
# shellcheck disable=SC2015
|
|
[ "$tun_status" = 'true' ] && _okcat 'Tun 状态:启用' || _failcat 'Tun 状态:关闭'
|
|
}
|
|
|
|
_tunoff() {
|
|
_tunstatus >/dev/null || return 0
|
|
sudo "$BIN_YQ" -i '.tun.enable = false' "$CLASH_CONFIG_MIXIN"
|
|
_merge_config_restart && _okcat "Tun 模式已关闭"
|
|
}
|
|
|
|
_tunon() {
|
|
_tunstatus 2>/dev/null && return 0
|
|
sudo "$BIN_YQ" -i '.tun.enable = true' "$CLASH_CONFIG_MIXIN"
|
|
_merge_config_restart
|
|
sleep 0.5s
|
|
sudo journalctl -u "$BIN_KERNEL_NAME" --since "1 min ago" | grep -E -m1 'unsupported kernel version|Start TUN listening error' && {
|
|
_tunoff >&/dev/null
|
|
_error_quit '不支持的内核版本'
|
|
}
|
|
_okcat "Tun 模式已开启"
|
|
}
|
|
|
|
function clashtun() {
|
|
case "$1" in
|
|
on)
|
|
_tunon
|
|
;;
|
|
off)
|
|
_tunoff
|
|
;;
|
|
*)
|
|
_tunstatus
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function clashupdate() {
|
|
local url=$(cat "$CLASH_CONFIG_URL")
|
|
local is_auto
|
|
|
|
case "$1" in
|
|
auto)
|
|
is_auto=true
|
|
[ -n "$2" ] && url=$2
|
|
;;
|
|
log)
|
|
sudo tail "${CLASH_UPDATE_LOG}" 2>/dev/null || _failcat "暂无更新日志"
|
|
return 0
|
|
;;
|
|
*)
|
|
[ -n "$1" ] && url=$1
|
|
;;
|
|
esac
|
|
|
|
# 如果没有提供有效的订阅链接(url为空或者不是http开头),则使用默认配置文件
|
|
[ "${url:0:4}" != "http" ] && {
|
|
_failcat "没有提供有效的订阅链接:使用 ${CLASH_CONFIG_RAW} 进行更新..."
|
|
url="file://$CLASH_CONFIG_RAW"
|
|
}
|
|
|
|
# 如果是自动更新模式,则设置定时任务
|
|
[ "$is_auto" = true ] && {
|
|
sudo grep -qs 'clashupdate' "$CLASH_CRON_TAB" || echo "0 0 */2 * * $_SHELL -i -c 'clashupdate $url'" | sudo tee -a "$CLASH_CRON_TAB" >&/dev/null
|
|
_okcat "已设置定时更新订阅" && return 0
|
|
}
|
|
|
|
_okcat '👌' "正在下载:原配置已备份..."
|
|
sudo cat "$CLASH_CONFIG_RAW" | sudo tee "$CLASH_CONFIG_RAW_BAK" >&/dev/null
|
|
|
|
_rollback() {
|
|
_failcat '🍂' "$1"
|
|
sudo cat "$CLASH_CONFIG_RAW_BAK" | sudo tee "$CLASH_CONFIG_RAW" >&/dev/null
|
|
_failcat '❌' "[$(date +"%Y-%m-%d %H:%M:%S")] 订阅更新失败:$url" 2>&1 | sudo tee -a "${CLASH_UPDATE_LOG}" >&/dev/null
|
|
_error_quit
|
|
}
|
|
|
|
_download_config "$CLASH_CONFIG_RAW" "$url" || _rollback "下载失败:已回滚配置"
|
|
_valid_config "$CLASH_CONFIG_RAW" || _rollback "转换失败:已回滚配置,转换日志:$BIN_SUBCONVERTER_LOG"
|
|
|
|
_merge_config_restart && _okcat '🍃' '订阅更新成功'
|
|
echo "$url" | sudo tee "$CLASH_CONFIG_URL" >&/dev/null
|
|
_okcat '✅' "[$(date +"%Y-%m-%d %H:%M:%S")] 订阅更新成功:$url" | sudo tee -a "${CLASH_UPDATE_LOG}" >&/dev/null
|
|
}
|
|
|
|
function clashmixin() {
|
|
case "$1" in
|
|
-e)
|
|
sudo vim "$CLASH_CONFIG_MIXIN" && {
|
|
_merge_config_restart && _okcat "配置更新成功,已重启生效"
|
|
}
|
|
;;
|
|
-r)
|
|
less -f "$CLASH_CONFIG_RUNTIME"
|
|
;;
|
|
*)
|
|
less -f "$CLASH_CONFIG_MIXIN"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function clashctl() {
|
|
case "$1" in
|
|
on)
|
|
clashon
|
|
;;
|
|
off)
|
|
clashoff
|
|
;;
|
|
ui)
|
|
clashui
|
|
;;
|
|
status)
|
|
shift
|
|
clashstatus "$@"
|
|
;;
|
|
|
|
tun)
|
|
shift
|
|
clashtun "$@"
|
|
;;
|
|
mixin)
|
|
shift
|
|
clashmixin "$@"
|
|
;;
|
|
secret)
|
|
shift
|
|
clashsecret "$@"
|
|
;;
|
|
update)
|
|
shift
|
|
clashupdate "$@"
|
|
;;
|
|
*)
|
|
cat <<EOF
|
|
|
|
Usage:
|
|
clash COMMAND [OPTION]
|
|
mihomo COMMAND [OPTION]
|
|
clashctl COMMAND [OPTION]
|
|
mihomoctl COMMAND [OPTION】
|
|
|
|
Commands:
|
|
on 开启代理
|
|
off 关闭代理
|
|
ui 面板地址
|
|
status 内核状况
|
|
tun [on|off] Tun 模式
|
|
mixin [-e|-r] Mixin 配置
|
|
secret [SECRET] Web 密钥
|
|
update [auto|log] 更新订阅
|
|
|
|
EOF
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function mihomoctl() {
|
|
clashctl "$@"
|
|
}
|
|
|
|
function clash() {
|
|
clashctl "$@"
|
|
}
|
|
|
|
function mihomo() {
|
|
clashctl "$@"
|
|
}
|