Users changing the panel port from the web UI had to SSH in and run 'systemctl restart 3m-ui' manually — easy to forget and not discoverable. Now both the 3m-ui entry script and 3m-ui.sh manager support: 3m-ui config show — display config.yaml 3m-ui config port <1-65535> — change port + auto-restart The interactive menu (running '3m-ui' with no args) also gains: 9. 修改面板端口 (interactive port change with current/new display) a. 卸载 3m-ui (moved from slot 9 to 'a') Flow: 1. Reads current port from config.yaml 2. Validates new port (1-65535, numeric) 3. sed replaces ' port: N' line in config.yaml 4. Restarts the service 5. Waits 1s, checks if active 6. Prints new access URL or failure message This closes the UX gap: web UI saves port → user runs '3m-ui config port 9000' → script restarts and confirms. feat(scripts): add config port command to 3m-ui management scripts Users changing the panel port from the web UI had to SSH in and run 'systemctl restart 3m-ui' manually — easy to forget and not discoverable. Now both the 3m-ui entry script and 3m-ui.sh manager support: 3m-ui config show — display config.yaml 3m-ui config port <1-65535> — change port + auto-restart The interactive menu (running '3m-ui' with no args) also gains: 9. 修改面板端口 (interactive port change with current/new display) a. 卸载 3m-ui (moved from slot 9 to 'a') Flow: 1. Reads current port from config.yaml 2. Validates new port (1-65535, numeric) 3. sed replaces ' port: N' line in config.yaml 4. Restarts the service 5. Waits 1s, checks if active 6. Prints new access URL or failure message This closes the UX gap: web UI saves port → user runs '3m-ui config port 9000' → script restarts and confirms. feat(scripts): add config port command to 3m-ui management scripts Users changing the panel port from the web UI had to SSH in and run 'systemctl restart 3m-ui' manually — easy to forget and not discoverable. Now both the 3m-ui entry script and 3m-ui.sh manager support: 3m-ui config show — display config.yaml 3m-ui config port <1-65535> — change port + auto-restart The interactive menu (running '3m-ui' with no args) also gains: 9. 修改面板端口 (interactive port change with current/new display) a. 卸载 3m-ui (moved from slot 9 to 'a') Flow: 1. Reads current port from config.yaml 2. Validates new port (1-65535, numeric) 3. sed replaces ' port: N' line in config.yaml 4. Restarts the service 5. Waits 1s, checks if active 6. Prints new access URL or failure message This closes the UX gap: web UI saves port → user runs '3m-ui config port 9000' → script restarts and confirms. feat(scripts): add config port command to 3m-ui management scripts Users changing the panel port from the web UI had to SSH in and run 'systemctl restart 3m-ui' manually — easy to forget and not discoverable. Now both the 3m-ui entry script and 3m-ui.sh manager support: 3m-ui config show — display config.yaml 3m-ui config port <1-65535> — change port + auto-restart The interactive menu (running '3m-ui' with no args) also gains: 9. 修改面板端口 (interactive port change with current/new display) a. 卸载 3m-ui (moved from slot 9 to 'a') Flow: 1. Reads current port from config.yaml 2. Validates new port (1-65535, numeric) 3. sed replaces ' port: N' line in config.yaml 4. Restarts the service 5. Waits 1s, checks if active 6. Prints new access URL or failure message This closes the UX gap: web UI saves port → user runs '3m-ui config port 9000' → script restarts and confirms. feat(scripts): add config port command to 3m-ui management scripts Users changing the panel port from the web UI had to SSH in and run 'systemctl restart 3m-ui' manually — easy to forget and not discoverable. Now both the 3m-ui entry script and 3m-ui.sh manager support: 3m-ui config show — display config.yaml 3m-ui config port <1-65535> — change port + auto-restart The interactive menu (running '3m-ui' with no args) also gains: 9. 修改面板端口 (interactive port change with current/new display) a. 卸载 3m-ui (moved from slot 9 to 'a') Flow: 1. Reads current port from config.yaml 2. Validates new port (1-65535, numeric) 3. sed replaces ' port: N' line in config.yaml 4. Restarts the service 5. Waits 1s, checks if active 6. Prints new access URL or failure message This closes the UX gap: web UI saves port → user runs '3m-ui config port 9000' → script restarts and confirms. feat(scripts): add config port command to 3m-ui management scripts Users changing the panel port from the web UI had to SSH in and run 'systemctl restart 3m-ui' manually — easy to forget and not discoverable. Now both the 3m-ui entry script and 3m-ui.sh manager support: 3m-ui config show — display config.yaml 3m-ui config port <1-65535> — change port + auto-restart The interactive menu (running '3m-ui' with no args) also gains: 9. 修改面板端口 (interactive port change with current/new display) a. 卸载 3m-ui (moved from slot 9 to 'a') Flow: 1. Reads current port from config.yaml 2. Validates new port (1-65535, numeric) 3. sed replaces ' port: N' line in config.yaml 4. Restarts the service 5. Waits 1s, checks if active 6. Prints new access URL or failure message This closes the UX gap: web UI saves port → user runs '3m-ui config port 9000' → script restarts and confirms. feat(scripts): add config port command to 3m-ui management scripts Users changing the panel port from the web UI had to SSH in and run 'systemctl restart 3m-ui' manually — easy to forget and not discoverable. Now both the 3m-ui entry script and 3m-ui.sh manager support: 3m-ui config show — display config.yaml 3m-ui config port <1-65535> — change port + auto-restart The interactive menu (running '3m-ui' with no args) also gains: 9. 修改面板端口 (interactive port change with current/new display) a. 卸载 3m-ui (moved from slot 9 to 'a') Flow: 1. Reads current port from config.yaml 2. Validates new port (1-65535, numeric) 3. sed replaces ' port: N' line in config.yaml 4. Restarts the service 5. Waits 1s, checks if active 6. Prints new access URL or failure message This closes the UX gap: web UI saves port → user runs '3m-ui config port 9000' → script restarts and confirms. feat(scripts): add config port command to 3m-ui management scripts Users changing the panel port from the web UI had to SSH in and run 'systemctl restart 3m-ui' manually — easy to forget and not discoverable. Now both the 3m-ui entry script and 3m-ui.sh manager support: 3m-ui config show — display config.yaml 3m-ui config port <1-65535> — change port + auto-restart The interactive menu (running '3m-ui' with no args) also gains: 9. 修改面板端口 (interactive port change with current/new display) a. 卸载 3m-ui (moved from slot 9 to 'a') Flow: 1. Reads current port from config.yaml 2. Validates new port (1-65535, numeric) 3. sed replaces ' port: N' line in config.yaml 4. Restarts the service 5. Waits 1s, checks if active 6. Prints new access URL or failure message This closes the UX gap: web UI saves port → user runs '3m-ui config port 9000' → script restarts and confirms. feat(scripts): add config port command to 3m-ui management scripts Users changing the panel port from the web UI had to SSH in and run 'systemctl restart 3m-ui' manually — easy to forget and not discoverable. Now both the 3m-ui entry script and 3m-ui.sh manager support: 3m-ui config show — display config.yaml 3m-ui config port <1-65535> — change port + auto-restart The interactive menu (running '3m-ui' with no args) also gains: 9. 修改面板端口 (interactive port change with current/new display) a. 卸载 3m-ui (moved from slot 9 to 'a') Flow: 1. Reads current port from config.yaml 2. Validates new port (1-65535, numeric) 3. sed replaces ' port: N' line in config.yaml 4. Restarts the service 5. Waits 1s, checks if active 6. Prints new access URL or failure message This closes the UX gap: web UI saves port → user runs '3m-ui config port 9000' → script restarts and confirms. feat(scripts): add config port command to 3m-ui management scripts Users changing the panel port from the web UI had to SSH in and run 'systemctl restart 3m-ui' manually — easy to forget and not discoverable. Now both the 3m-ui entry script and 3m-ui.sh manager support: 3m-ui config show — display config.yaml 3m-ui config port <1-65535> — change port + auto-restart The interactive menu (running '3m-ui' with no args) also gains: 9. 修改面板端口 (interactive port change with current/new display) a. 卸载 3m-ui (moved from slot 9 to 'a') Flow: 1. Reads current port from config.yaml 2. Validates new port (1-65535, numeric) 3. sed replaces ' port: N' line in config.yaml 4. Restarts the service 5. Waits 1s, checks if active 6. Prints new access URL or failure message This closes the UX gap: web UI saves port → user runs '3m-ui config port 9000' → script restarts and confirms. feat(scripts): add config port command to 3m-ui management scripts Users changing the panel port from the web UI had to SSH in and run 'systemctl restart 3m-ui' manually — easy to forget and not discoverable. Now both the 3m-ui entry script and 3m-ui.sh manager support: 3m-ui config show — display config.yaml 3m-ui config port <1-65535> — change port + auto-restart The interactive menu (running '3m-ui' with no args) also gains: 9. 修改面板端口 (interactive port change with current/new display) a. 卸载 3m-ui (moved from slot 9 to 'a') Flow: 1. Reads current port from config.yaml 2. Validates new port (1-65535, numeric) 3. sed replaces ' port: N' line in config.yaml 4. Restarts the service 5. Waits 1s, checks if active 6. Prints new access URL or failure message This closes the UX gap: web UI saves port → user runs '3m-ui config port 9000' → script restarts and confirms. feat(scripts): add config port command to 3m-ui management scripts Users changing the panel port from the web UI had to SSH in and run 'systemctl restart 3m-ui' manually — easy to forget and not discoverable. Now both the 3m-ui entry script and 3m-ui.sh manager support: 3m-ui config show — display config.yaml 3m-ui config port <1-65535> — change port + auto-restart The interactive menu (running '3m-ui' with no args) also gains: 9. 修改面板端口 (interactive port change with current/new display) a. 卸载 3m-ui (moved from slot 9 to 'a') Flow: 1. Reads current port from config.yaml 2. Validates new port (1-65535, numeric) 3. sed replaces ' port: N' line in config.yaml 4. Restarts the service 5. Waits 1s, checks if active 6. Prints new access URL or failure message This closes the UX gap: web UI saves port → user runs '3m-ui config port 9000' → script restarts and confirms.
175 lines
5.6 KiB
Bash
175 lines
5.6 KiB
Bash
#!/bin/sh
|
|
# 3m-ui unified management entrypoint.
|
|
# Installed as /usr/local/bin/3m-ui.
|
|
# The actual Go application binary is /usr/local/lib/3m-ui/3m-ui-bin.
|
|
|
|
set -eu
|
|
|
|
BASE="/usr/local/lib/3m-ui"
|
|
MANAGER="$BASE/3m-ui.sh"
|
|
INSTALLER="$BASE/install.sh"
|
|
UPDATER="$BASE/update.sh"
|
|
UNINSTALLER="$BASE/uninstall.sh"
|
|
APP_BIN="$BASE/3m-ui-bin"
|
|
CONFIG_FILE="/etc/3m-ui/config.yaml"
|
|
|
|
run_script() {
|
|
script="$1"
|
|
shift
|
|
[ -x "$script" ] || {
|
|
printf '%s\n' "3m-ui management script is missing: $script" >&2
|
|
exit 1
|
|
}
|
|
exec "$script" "$@"
|
|
}
|
|
|
|
menu() {
|
|
while :; do
|
|
printf '\n'
|
|
printf '%s\n' '╭────────────────────────────────────╮'
|
|
printf '%s\n' '│ 3m-ui 管理控制台 │'
|
|
printf '%s\n' '│ Mihomo Core Management UI │'
|
|
printf '%s\n' '╰────────────────────────────────────╯'
|
|
printf '\n'
|
|
printf '%s\n' ' 1. 安装 / 修复 3m-ui'
|
|
printf '%s\n' ' 2. 更新 3m-ui'
|
|
printf '%s\n' ' 3. 查看运行状态'
|
|
printf '%s\n' ' 4. 启动 3m-ui'
|
|
printf '%s\n' ' 5. 重启 3m-ui'
|
|
printf '%s\n' ' 6. 停止 3m-ui'
|
|
printf '%s\n' ' 7. 查看日志'
|
|
printf '%s\n' ' 8. 查看版本'
|
|
printf '%s\n' ' 9. 修改面板端口'
|
|
printf '%s\n' ' a. 卸载 3m-ui'
|
|
printf '%s\n' ' 0. 退出'
|
|
printf '\n请选择 [0-9a]: '
|
|
IFS= read -r choice || exit 0
|
|
case "$choice" in
|
|
1) run_script "$INSTALLER" ;;
|
|
2) run_script "$UPDATER" ;;
|
|
3) run_script "$MANAGER" status ;;
|
|
4) run_script "$MANAGER" start ;;
|
|
5) run_script "$MANAGER" restart ;;
|
|
6) run_script "$MANAGER" stop ;;
|
|
7) run_script "$MANAGER" logs ;;
|
|
8) run_script "$MANAGER" version ;;
|
|
9) change_port ;;
|
|
a|A) run_script "$UNINSTALLER" ;;
|
|
0) exit 0 ;;
|
|
*) printf '%s\n' '无效选择,请重新输入。' ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
init_system() {
|
|
if [ -d /run/systemd/system ] && command -v systemctl >/dev/null 2>&1; then
|
|
printf '%s' systemd
|
|
elif command -v rc-service >/dev/null 2>&1; then
|
|
printf '%s' openrc
|
|
else
|
|
printf '%s' unsupported
|
|
fi
|
|
}
|
|
|
|
service_action() {
|
|
action="$1"
|
|
case "$(init_system)" in
|
|
systemd) systemctl "$action" 3m-ui ;;
|
|
openrc) rc-service 3m-ui "$action" ;;
|
|
*) printf '%s\n' '未检测到 systemd 或 OpenRC。' >&2; exit 1 ;;
|
|
esac
|
|
}
|
|
|
|
status() {
|
|
case "$(init_system)" in
|
|
systemd) systemctl --no-pager --full status 3m-ui || true ;;
|
|
openrc) rc-service 3m-ui status || true ;;
|
|
*) printf '%s\n' 'init: unsupported' ;;
|
|
esac
|
|
printf '\n'
|
|
if [ -x "$APP_BIN" ]; then
|
|
printf '%s\n' "应用程序: $APP_BIN"
|
|
"$APP_BIN" --version 2>/dev/null || true
|
|
else
|
|
printf '%s\n' '应用程序二进制不存在。'
|
|
fi
|
|
}
|
|
|
|
logs() {
|
|
case "$(init_system)" in
|
|
systemd) journalctl -u 3m-ui -n 100 --no-pager ;;
|
|
openrc) tail -n 100 /var/log/3m-ui/3m-ui.log 2>/dev/null || printf '%s\n' '未找到日志文件。' ;;
|
|
*) printf '%s\n' '未找到可用的日志系统。' ;;
|
|
esac
|
|
}
|
|
|
|
version() {
|
|
if [ -x "$APP_BIN" ]; then
|
|
"$APP_BIN" --version
|
|
else
|
|
printf '%s\n' '3m-ui 未安装。' >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
need_root() {
|
|
[ "$(id -u)" -eq 0 ] || { printf '%s\n' '请使用 root 运行 3m-ui 管理命令。' >&2; exit 1; }
|
|
}
|
|
|
|
change_port() {
|
|
if [ ! -f "$CONFIG_FILE" ]; then
|
|
printf '%s\n' "配置文件不存在: $CONFIG_FILE" >&2
|
|
return 1
|
|
fi
|
|
current=$(awk '/^ port:/ {print $2; exit}' "$CONFIG_FILE" 2>/dev/null || echo "8080")
|
|
printf '当前面板端口: %s\n' "$current"
|
|
printf '输入新端口 (1-65535, 回车取消): '
|
|
IFS= read -r new_port || return 0
|
|
[ -z "$new_port" ] && return 0
|
|
case "$new_port" in
|
|
''|*[!0-9]*) printf '%s\n' '无效端口。' >&2; return 1 ;;
|
|
esac
|
|
[ "$new_port" -ge 1 ] 2>/dev/null && [ "$new_port" -le 65535 ] 2>/dev/null || {
|
|
printf '%s\n' '端口必须在 1-65535 范围内。' >&2
|
|
return 1
|
|
}
|
|
[ "$new_port" = "$current" ] && {
|
|
printf '%s\n' '端口未变更。'
|
|
return 0
|
|
}
|
|
sed -i "s/^ port: .*/ port: $new_port/" "$CONFIG_FILE"
|
|
printf '%s\n' "端口已更改: $current → $new_port"
|
|
printf '%s\n' '正在重启 3m-ui...'
|
|
service_action restart
|
|
sleep 1
|
|
if service_action status >/dev/null 2>&1; then
|
|
printf '%s\n' "✓ 3m-ui 已重启。新地址: http://0.0.0.0:$new_port"
|
|
else
|
|
printf '%s\n' '✗ 3m-ui 启动失败,请检查日志。' >&2
|
|
fi
|
|
}
|
|
|
|
main() {
|
|
need_root
|
|
cmd=${1:-}
|
|
case "$cmd" in
|
|
status) status ;;
|
|
start) service_action start ;;
|
|
restart) service_action restart ;;
|
|
stop) service_action stop ;;
|
|
logs) logs ;;
|
|
version) version ;;
|
|
config) shift; run_script "$MANAGER" config "$@" ;;
|
|
help|-h|--help)
|
|
printf '%s\n' '用法: 3m-ui [status|start|restart|stop|logs|version|config|help]'
|
|
printf '%s\n' ' 3m-ui config show 查看配置'
|
|
printf '%s\n' ' 3m-ui config port <端口号> 修改端口并重启'
|
|
printf '%s\n' '不带参数直接运行 3m-ui 将进入交互式管理菜单。'
|
|
;;
|
|
'') menu ;;
|
|
*) printf '%s\n' "未知命令: $cmd" >&2; exit 2 ;;
|
|
esac
|
|
}
|
|
|
|
main "$@"
|