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

235 lines
6.0 KiB
Bash

#!/bin/bash
set -e
# ============================================
# 串口关机控制器 - 安装脚本
# ============================================
INSTALL_DIR="/opt/ttyshutdown"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# 颜色定义
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 install.sh"
exit 1
fi
}
# 扫描可用串口
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() {
echo -e "${CYAN}========================================${NC}"
echo -e "${CYAN} 串口关机控制器 - 安装向导${NC}"
echo -e "${CYAN}========================================${NC}"
echo ""
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
echo " [$i] $p ($desc)"
((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
generate_config() {
local port="$1"
local baud_rate="$2"
local shutdown_word="$3"
cat > "${INSTALL_DIR}/config.json" <<EOF
{
"port": "${port}",
"baudRate": ${baud_rate},
"shutdownWord": "${shutdown_word}"
}
EOF
info "已生成配置文件: ${INSTALL_DIR}/config.json"
}
# 生成 send_signal.sh
generate_send_signal() {
local port="$1"
local baud_rate="$2"
local shutdown_word="$3"
cat > "/usr/lib/systemd/system-shutdown/send_signal.sh" <<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 "/usr/lib/systemd/system-shutdown/send_signal.sh"
info "已安装关机钩子: /usr/lib/systemd/system-shutdown/send_signal.sh"
}
# 生成 systemd service
generate_service() {
cat > /etc/systemd/system/ttyshutdown.service <<EOF
[Unit]
Description=ttyshutdown
[Service]
Type=simple
User=root
WorkingDirectory=${INSTALL_DIR}
ExecStart=${INSTALL_DIR}/shutdown
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
EOF
info "已生成 systemd 服务: /etc/systemd/system/ttyshutdown.service"
}
# 主安装流程
main() {
check_root
# 1. 选择串口
select_serial_port
info "已选择串口: $SELECTED_PORT"
# 2. 可选参数
local baud_rate=115200
local shutdown_word="SHUTDOWN"
echo ""
read -rp "波特率 [默认 115200]: " input_baud
if [ -n "$input_baud" ]; then
baud_rate="$input_baud"
fi
read -rp "关机指令 [默认 SHUTDOWN]: " input_word
if [ -n "$input_word" ]; then
shutdown_word="$input_word"
fi
echo ""
echo -e "${CYAN}=== 确认配置 ===${NC}"
echo " 串口设备: $SELECTED_PORT"
echo " 波特率: $baud_rate"
echo " 关机指令: $shutdown_word"
echo " 安装目录: $INSTALL_DIR"
echo ""
read -rp "确认安装? [Y/n]: " confirm
if [[ "$confirm" =~ ^[Nn] ]]; then
warn "已取消安装"
exit 0
fi
# 3. 检查二进制文件
if [ ! -f "${SCRIPT_DIR}/shutdown" ]; then
error "未找到预编译的 shutdown 二进制文件"
echo "请将 shutdown 二进制文件复制到 ${SCRIPT_DIR} 目录下"
exit 1
fi
# 4. 安装文件
mkdir -p "$INSTALL_DIR"
cp "${SCRIPT_DIR}/shutdown" "${INSTALL_DIR}/shutdown"
chmod +x "${INSTALL_DIR}/shutdown"
# 5. 生成配置
generate_config "$SELECTED_PORT" "$baud_rate" "$shutdown_word"
# 6. 安装关机钩子
mkdir -p /usr/lib/systemd/system-shutdown
generate_send_signal "$SELECTED_PORT" "$baud_rate" "$shutdown_word"
# 7. 生成并启用 systemd 服务
generate_service
systemctl daemon-reload
systemctl enable ttyshutdown.service
systemctl start ttyshutdown.service
echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} 安装完成!${NC}"
echo -e "${GREEN}========================================${NC}"
echo -e " 服务状态: ${CYAN}systemctl status ttyshutdown${NC}"
echo -e " 查看日志: ${CYAN}journalctl -u ttyshutdown -f${NC}"
echo -e " 停止服务: ${CYAN}systemctl stop ttyshutdown${NC}"
echo -e " 卸载: ${CYAN}sudo bash ${SCRIPT_DIR}/uninstall.sh${NC}"
}
main