带模组的Minecraft服务器每日自动重启脚本异常问题排查咨询
带模组的Minecraft服务器每日自动重启脚本异常问题排查咨询
问题背景
我写了一个用于Minecraft模组服务器每日自动重启的shell脚本,通过tmux向指定会话发送指令,同时设置了crontab定时任务每日21点执行。脚本里的倒计时通知都能正常发送,但到了执行/stop命令和后续启动服务器的./run.sh步骤时就失效了,想请教下可能的原因和解决办法?
我的脚本内容如下:
# 发送30分钟重启提醒 tmux send-keys -t VHS "/say §cServer restarting in §l30 minutes. §rPlease get ready to log off." Enter # 等待29分30秒 sleep 1770s # 发送倒计时提醒 tmux send-keys -t VHS "/say §cServer is restarting in §l30 seconds! §rthe restart will take aproximately 5 minutes!" Enter sleep 20s tmux send-keys -t VHS "/say §cServer is restarting in §l10 seconds!" Enter sleep 5s tmux send-keys -t VHS "/say §cServer is restarting in §l5 seconds!" Enter sleep 1s tmux send-keys -t VHS "/say §cServer is restarting in §l4 seconds!" Enter sleep 1s tmux send-keys -t VHS "/say §cServer is restarting in §l3 seconds!" Enter sleep 1s tmux send-keys -t VHS "/say §cServer is restarting in §l2 seconds!" Enter sleep 1s tmux send-keys -t VHS "/say §cServer is restarting in §l1 second!" Enter sleep 1s # 停止服务器 tmux send-keys -t VHS "/stop" Enter # 等待5分钟 sleep 300s # 重启服务器 tmux send-keys -t VHS "./run.sh" Enter
crontab定时任务配置:
0 21 * * * /VHServer/restart.sh
可能的原因分析
根据你的场景,我整理了几个最可能导致/stop和./run.sh失效的原因:
- tmux会话的上下文匹配问题
crontab的执行环境和你手动登录shell时的环境完全不同:
- 如果你是用普通用户创建的
VHStmux会话,但crontab默认以root用户执行,那么root用户下找不到这个会话,后续的tmux send-keys指令就会静默失败。 - 即使是同一用户,crontab执行时没有加载用户的shell配置(比如
~/.bashrc、~/.profile),可能缺少tmux的环境变量,导致无法正确识别会话。
相对路径的陷阱
脚本最后一行的./run.sh使用了相对路径,而crontab执行脚本时的工作目录默认是用户的家目录(比如/root或/home/youruser),不是你的Minecraft服务器所在的/VHServer目录,所以会找不到run.sh文件,导致启动失败。服务器停止后的tmux会话状态变化
当你发送/stop指令后,Minecraft服务器进程会终止,可能导致绑定的tmux会话也随之关闭(如果会话是为了运行服务器而创建的)。这种情况下,后续发送./run.sh的指令就没有对应的会话可以接收了。权限不足
- 你的
restart.sh脚本可能没有执行权限,可以用chmod +x /VHServer/restart.sh确认并添加权限。 - crontab执行用户可能没有操作tmux会话、读写服务器目录或执行
run.sh的权限。
解决方案建议
针对上面的问题,你可以按以下步骤排查和修复:
- 确保crontab使用正确的用户执行
修改crontab任务,指定创建tmux会话的用户来执行脚本,比如:
0 21 * * * su - yourusername -c "/VHServer/restart.sh"
替换yourusername为实际运行tmux会话的用户。
将所有相对路径改为绝对路径
把脚本里的./run.sh改成绝对路径,比如/VHServer/run.sh,确保无论工作目录在哪里都能找到启动脚本。验证tmux会话的存在性
在脚本中添加会话检查步骤,避免指令发送到不存在的会话:
# 检查VHS会话是否存在 if ! tmux list-sessions | grep -q "VHS"; then echo "VHS tmux session not found!" >> /VHServer/restart.log exit 1 fi
同时可以在关键步骤添加日志输出,方便排查哪一步出错:
echo "Sending /stop command at $(date)" >> /VHServer/restart.log tmux send-keys -t VHS "/stop" Enter
- 处理服务器停止后的会话问题
如果服务器停止后tmux会话会关闭,你可以修改脚本,在发送/stop后重新创建会话再启动服务器:
# 停止服务器后等待关闭 tmux send-keys -t VHS "/stop" Enter sleep 300s # 检查会话是否存在,不存在则创建 if ! tmux list-sessions | grep -q "VHS"; then tmux new-session -d -s VHS fi # 发送启动指令 tmux send-keys -t VHS "/VHServer/run.sh" Enter
- 测试脚本的执行环境
手动模拟crontab的环境执行脚本,排查环境差异:
su - root -c "/VHServer/restart.sh" # 如果crontab用root执行
观察执行过程中是否有错误提示,帮助定位问题。
备注:内容来源于stack exchange,提问作者PerplexApple




