感谢gemini
可使用systemd管理napcat,不影响原来的TUI,方便开机运行等用途
已在ubuntu24.04.3测试
脚本内容:
#!/bin/bash
# 确定用户与目录 (适配 Systemd 环境)
TARGET_USER="${USER:-$(whoami)}"
TARGET_USER_HOME="${HOME:-/home/$TARGET_USER}"
# 核心路径定义
INSTALL_BASE_DIR="$TARGET_USER_HOME/Napcat"
RUN_DIR="$INSTALL_BASE_DIR/run"
LOG_DIR="$INSTALL_BASE_DIR/log"
# QQ 程序路径
QQ_EXECUTABLE="$INSTALL_BASE_DIR/opt/QQ/qq"
# Napcat 配置文件路径
NAPCAT_DIR="$INSTALL_BASE_DIR/opt/QQ/resources/app/app_launcher/napcat"
CONFIG_DIR="$NAPCAT_DIR/config"
# 确保运行时目录存在
mkdir -p "$RUN_DIR" "$LOG_DIR"
# 递归获取子进程 PID (用于彻底停止)
_get_all_descendant_pids() {
local pids=$(pgrep -P "$1")
for pid in $pids; do
echo "$pid"
_get_all_descendant_pids "$pid"
done
}
# 自动从配置文件中获取第一个 QQ 账号
get_qq_account() {
local config_file
config_file=$(ls "$CONFIG_DIR"/onebot11_*.json 2>/dev/null | head -n 1)
if [[ -z "$config_file" ]]; then
echo "错误: 在 $CONFIG_DIR 下未找到配置文件 (onebot11_*.json)。"
exit 1
fi
local filename=$(basename "$config_file")
if [[ "$filename" =~ onebot11_([0-9]+)\.json ]]; then
echo "${BASH_REMATCH[1]}"
else
echo "错误: 无法从文件名 $filename 中解析 QQ 号。"
exit 1
fi
}
stop_napcat() {
echo ">>> 正在停止 Napcat..."
local candidate_pids
local final_pids=()
readarray -t candidate_pids < <(pgrep -f ".*/qq --no-sandbox -q [0-9]{4,}")
if [[ ${#candidate_pids[@]} -gt 0 ]]; then
for pid in "${candidate_pids[@]}"; do
local ppid=$(ps -o ppid= -p "$pid" | tr -d ' ')
local is_child=false
for other_pid in "${candidate_pids[@]}"; do
if [[ "$ppid" == "$other_pid" ]]; then
is_child=true; break
fi
done
if ! $is_child; then final_pids+=("$pid"); fi
done
fi
if [[ ${#final_pids[@]} -eq 0 ]]; then
echo "未发现正在运行的 Napcat 进程。"
[[ -f "$RUN_DIR/napcat.pid" ]] && rm -f "$RUN_DIR/napcat.pid"
return 0
fi
echo "发现进程 (PID: ${final_pids[*]}), 正在终止..."
local all_stopped=true
for pid in "${final_pids[@]}"; do
local all_pids_to_kill=("$pid" $(_get_all_descendant_pids "$pid"))
kill "${all_pids_to_kill[@]}" 2>/dev/null
done
sleep 2
for pid in "${final_pids[@]}"; do
if kill -0 "$pid" 2>/dev/null; then
local all_pids_to_kill=("$pid" $(_get_all_descendant_pids "$pid"))
echo "进程顽固,执行强制清理 (kill -9)..."
kill -9 "${all_pids_to_kill[@]}" 2>/dev/null
sleep 1
fi
if kill -0 "$pid" 2>/dev/null; then all_stopped=false; fi
done
if $all_stopped; then
echo "Napcat 已停止。"
rm -f "$RUN_DIR/napcat.pid"
else
echo "警告: 部分进程可能未停止,请手动检查。"
exit 1
fi
}
start_napcat() {
echo ">>> 准备启动 Napcat..."
if ! command -v xvfb-run &> /dev/null; then
echo "错误: 未找到 'xvfb-run' 命令。请先安装。"
exit 1
fi
local qq_account
qq_account=$(get_qq_account)
if [[ $? -ne 0 ]]; then echo "$qq_account"; exit 1; fi
local log_file="$LOG_DIR/napcat_${qq_account}.log"
echo "目标账号: $qq_account"
echo "日志路径: $log_file"
echo "注意: 日志将同时输出到 屏幕(Systemd) 和 文件。"
# 清理旧进程
stop_napcat > /dev/null 2>&1
echo "正在启动进程..."
echo "$$" > "$RUN_DIR/napcat.pid"
exec > >(tee -a "$log_file") 2>&1
exec xvfb-run -a "$QQ_EXECUTABLE" --no-sandbox -q "$qq_account"
}
case "$1" in
start)
start_napcat
;;
stop)
stop_napcat
;;
restart)
stop_napcat
sleep 1
start_napcat
;;
*)
echo "用法: $0 {start|stop|restart}"
exit 1
;;
esac
配套的systemd服务文件:
[Unit]
Description=Napcat QQ Bot Service
After=network.target network-online.target
Wants=network-online.target
[Service]
# 【修改】替换为你的实际用户名
User=ubuntu
Group=ubuntu
Type=simple
#替换你的napcat安装目录
WorkingDirectory=/home/ubuntu/Napcat
# 指向该脚本路径
ExecStart=/bin/bash /home/ubuntu/Napcat/napcat.sh start
# 停止时执行清理逻辑
ExecStop=/bin/bash /home/ubuntu/Napcat/napcat.sh stop
Restart=on-failure
RestartSec=10s
# 资源限制(可选,防止内存泄漏)
# MemoryMax=1G
[Install]
WantedBy=multi-user.target
感谢gemini
可使用systemd管理napcat,不影响原来的TUI,方便开机运行等用途
已在ubuntu24.04.3测试
脚本内容:
配套的systemd服务文件: