Files
poweroff-protection/poweroff_linux/change_port.sh
2026-05-14 17:53:52 +08:00

238 lines
6.2 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
set -e
# ============================================
# 串口关机控制器 - 更换串口脚本
# ============================================
INSTALL_DIR="/opt/ttyshutdown"
CONFIG_FILE="${INSTALL_DIR}/config.json"
SIGNAL_SCRIPT="/usr/lib/systemd/system-shutdown/send_signal.sh"
SERVICE_NAME="ttyshutdown"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; }
# 检查 root 权限
check_root() {
if [ "$(id -u)" -ne 0 ]; then
error "请使用 root 权限运行此脚本: sudo bash change_port.sh"
exit 1
fi
}
# 检查是否已安装
check_installed() {
if [ ! -f "$CONFIG_FILE" ]; then
error "未找到配置文件 $CONFIG_FILE,请先运行 install.sh 安装"
exit 1
fi
}
# 读取当前配置
read_current_config() {
CURRENT_PORT=$(grep -oP '"port"\s*:\s*"\K[^"]+' "$CONFIG_FILE")
CURRENT_BAUD=$(grep -oP '"baudRate"\s*:\s*\K[0-9]+' "$CONFIG_FILE")
CURRENT_WORD=$(grep -oP '"shutdownWord"\s*:\s*"\K[^"]+' "$CONFIG_FILE")
echo -e "${CYAN}=== 当前配置 ===${NC}"
echo " 串口设备: $CURRENT_PORT"
echo " 波特率: $CURRENT_BAUD"
echo " 关机指令: $CURRENT_WORD"
echo ""
}
# 扫描可用串口
scan_serial_ports() {
local ports=()
for pattern in "ttyUSB*" "ttyACM*" "ttyS*"; do
for dev in /dev/$pattern; do
if [ -e "$dev" ]; then
ports+=("$dev")
fi
done
done
echo "${ports[@]}"
}
# 交互选择串口
select_serial_port() {
local ports
ports=$(scan_serial_ports)
if [ -z "$ports" ]; then
warn "未检测到串口设备"
echo -e "请手动输入串口设备路径 (如 ${YELLOW}/dev/ttyUSB0${NC}): "
read -r SELECTED_PORT
if [ ! -e "$SELECTED_PORT" ]; then
warn "设备 $SELECTED_PORT 当前不存在,仍将配置(设备可能稍后接入)"
fi
return
fi
local port_array=($ports)
echo -e "检测到以下串口设备:${GREEN}"
local i=1
for p in "${port_array[@]}"; do
local desc=""
case "$p" in
/dev/ttyUSB*) desc="USB转串口" ;;
/dev/ttyACM*) desc="USB CDC虚拟串口" ;;
/dev/ttyS*) desc="原生串口(COM口)" ;;
esac
local marker=""
if [ "$p" = "$CURRENT_PORT" ]; then
marker=" ${YELLOW}<-- 当前${NC}"
fi
echo " [$i] $p ($desc)${marker}"
((i++))
done
echo -e "${NC}"
local last_index=${#port_array[@]}
echo " [$((last_index + 1))] 手动输入其他路径"
echo ""
local choice
while true; do
read -rp "请选择串口 [1-$((last_index + 1))]: " choice
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$((last_index + 1))" ]; then
break
fi
error "无效选择,请重新输入"
done
if [ "$choice" -le "$last_index" ]; then
SELECTED_PORT="${port_array[$((choice - 1))]}"
else
read -rp "请输入串口设备路径: " SELECTED_PORT
if [ -z "$SELECTED_PORT" ]; then
error "路径不能为空"
exit 1
fi
fi
}
# 更新 config.json
update_config() {
local port="$1"
local baud_rate="$2"
local shutdown_word="$3"
cat > "$CONFIG_FILE" <<EOF
{
"port": "${port}",
"baudRate": ${baud_rate},
"shutdownWord": "${shutdown_word}"
}
EOF
info "已更新配置文件: $CONFIG_FILE"
}
# 更新 send_signal.sh
update_send_signal() {
local port="$1"
local baud_rate="$2"
local shutdown_word="$3"
cat > "$SIGNAL_SCRIPT" <<EOF
#!/bin/bash
TTY_DEVICE="${port}"
ACTION=\$1
if [ "\$ACTION" = "poweroff" ] ; then
if [ -w "\$TTY_DEVICE" ]; then
stty -F "\$TTY_DEVICE" ${baud_rate} cs8 -cstopb -parenb
printf "ok\r\n" > "\$TTY_DEVICE"
fi
fi
exit 0
EOF
chmod +x "$SIGNAL_SCRIPT"
info "已更新关机钩子: $SIGNAL_SCRIPT"
}
# 重启服务
restart_service() {
systemctl restart "$SERVICE_NAME"
info "已重启服务: $SERVICE_NAME"
}
# 主流程
main() {
check_root
check_installed
echo -e "${CYAN}========================================${NC}"
echo -e "${CYAN} 串口关机控制器 - 更换串口${NC}"
echo -e "${CYAN}========================================${NC}"
echo ""
# 1. 显示当前配置
read_current_config
# 2. 选择新串口
select_serial_port
if [ "$SELECTED_PORT" = "$CURRENT_PORT" ]; then
warn "选择的新串口与当前串口相同,无需更改"
exit 0
fi
info "新串口: $SELECTED_PORT"
# 3. 可选修改波特率和关机指令
local new_baud="$CURRENT_BAUD"
local new_word="$CURRENT_WORD"
echo ""
read -rp "波特率 [当前 $CURRENT_BAUD,回车保持]: " input_baud
if [ -n "$input_baud" ]; then
new_baud="$input_baud"
fi
read -rp "关机指令 [当前 $CURRENT_WORD,回车保持]: " input_word
if [ -n "$input_word" ]; then
new_word="$input_word"
fi
# 4. 确认
echo ""
echo -e "${CYAN}=== 确认更改 ===${NC}"
echo " 串口设备: $CURRENT_PORT -> $SELECTED_PORT"
[ "$new_baud" != "$CURRENT_BAUD" ] && echo " 波特率: $CURRENT_BAUD -> $new_baud"
[ "$new_word" != "$CURRENT_WORD" ] && echo " 关机指令: $CURRENT_WORD -> $new_word"
echo ""
read -rp "确认更改? [Y/n]: " confirm
if [[ "$confirm" =~ ^[Nn] ]]; then
warn "已取消"
exit 0
fi
# 5. 执行更改
update_config "$SELECTED_PORT" "$new_baud" "$new_word"
update_send_signal "$SELECTED_PORT" "$new_baud" "$new_word"
restart_service
echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}串口更换完成!${NC}重启或重启ttyshutdown服务后生效"
echo -e "${GREEN}========================================${NC}"
echo -e " 新串口: ${CYAN}$SELECTED_PORT${NC}"
echo -e " 波特率: ${CYAN}$new_baud${NC}"
echo -e " 服务状态: ${CYAN}systemctl status ttyshutdown${NC}"
echo -e " 查看日志: ${CYAN}journalctl -u ttyshutdown -f${NC}"
}
main