From 2fd6992574389779e99830f2ff9dbb0746a755d7 Mon Sep 17 00:00:00 2001 From: Z User Date: Sun, 30 Aug 2026 09:41:36 +0000 Subject: [PATCH] feat(scripts): add config port command to 3m-ui management scripts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- scripts/3m-ui | 47 +++++++++++++++++++++++++++++++++++---- scripts/3m-ui.sh | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 4 deletions(-) diff --git a/scripts/3m-ui b/scripts/3m-ui index bd47303..a5a6fb4 100644 --- a/scripts/3m-ui +++ b/scripts/3m-ui @@ -11,6 +11,7 @@ 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" @@ -38,9 +39,10 @@ menu() { printf '%s\n' ' 6. 停止 3m-ui' printf '%s\n' ' 7. 查看日志' printf '%s\n' ' 8. 查看版本' - printf '%s\n' ' 9. 卸载 3m-ui' + printf '%s\n' ' 9. 修改面板端口' + printf '%s\n' ' a. 卸载 3m-ui' printf '%s\n' ' 0. 退出' - printf '\n请选择 [0-9]: ' + printf '\n请选择 [0-9a]: ' IFS= read -r choice || exit 0 case "$choice" in 1) run_script "$INSTALLER" ;; @@ -51,7 +53,8 @@ menu() { 6) run_script "$MANAGER" stop ;; 7) run_script "$MANAGER" logs ;; 8) run_script "$MANAGER" version ;; - 9) run_script "$UNINSTALLER" ;; + 9) change_port ;; + a|A) run_script "$UNINSTALLER" ;; 0) exit 0 ;; *) printf '%s\n' '无效选择,请重新输入。' ;; esac @@ -113,6 +116,39 @@ 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:-} @@ -123,8 +159,11 @@ main() { 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|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 ;; diff --git a/scripts/3m-ui.sh b/scripts/3m-ui.sh index a0d8332..140f7ab 100644 --- a/scripts/3m-ui.sh +++ b/scripts/3m-ui.sh @@ -11,6 +11,7 @@ APP_BIN="$BASE/3m-ui-bin" VERSION_FILE="$BASE/VERSION" DATA_DIR="/var/lib/3m-ui" CONFIG_DIR="/etc/3m-ui" +CONFIG_FILE="$CONFIG_DIR/config.yaml" SERVICE="3m-ui" say() { printf '%s\n' "$*"; } @@ -101,6 +102,57 @@ uninstall() { say "Mihomo was not removed." } +config() { + action="${1:-show}" + case "$action" in + show) + if [ -f "$CONFIG_FILE" ]; then + say "Config file: $CONFIG_FILE" + say "---" + cat "$CONFIG_FILE" + else + err "Config file not found: $CONFIG_FILE" + fi + ;; + port) + new_port="$2" + case "$new_port" in + ''|*[!0-9]*) err "Usage: 3m-ui config port <1-65535>" ;; + esac + [ "$new_port" -ge 1 ] 2>/dev/null && [ "$new_port" -le 65535 ] 2>/dev/null || err "Port must be 1-65535." + [ -f "$CONFIG_FILE" ] || err "Config file not found: $CONFIG_FILE" + # Read current port + old_port=$(awk '/^ port:/ {print $2; exit}' "$CONFIG_FILE" 2>/dev/null || echo "8080") + if [ "$old_port" = "$new_port" ]; then + say "Port is already $new_port — no change needed." + return 0 + fi + # Replace port in config.yaml + sed -i "s/^ port: .*/ port: $new_port/" "$CONFIG_FILE" + say "Port changed: $old_port → $new_port" + say "Restarting 3m-ui to apply..." + service_action restart + sleep 1 + if service_is_active; then + say "✓ 3m-ui restarted. Access: http://0.0.0.0:$new_port" + else + say "✗ 3m-ui failed to start. Check logs: 3m-ui logs" + fi + ;; + *) + err "Unknown config action: $action. Use 'show' or 'port '." + ;; + esac +} + +service_is_active() { + case "$(init_system)" in + systemd) systemctl is-active --quiet "$SERVICE" ;; + openrc) rc-service "$SERVICE" status >/dev/null 2>&1 ;; + *) return 1 ;; + esac +} + usage() { cat < @@ -112,9 +164,14 @@ Commands: stop Stop 3m-ui logs Show recent service logs version Show installed 3m-ui version + config Show or edit config (see below) uninstall Remove 3m-ui but preserve data/config help Show this help +Config sub-commands: + 3m-ui config show Display current config.yaml + 3m-ui config port <1-65535> Change panel port and restart + Run '3m-ui' without arguments to open the interactive management menu. EOF } @@ -129,6 +186,7 @@ main() { stop) service_action stop ;; logs) logs ;; version) version ;; + config) shift; config "$@" ;; uninstall) uninstall ;; help|-h|--help) usage ;; '')