Linux下DotNet游戏服务器Screen会话内重启问题求助
解决Screen会话内部重启.NET游戏服务器的问题
我完全懂你遇到的麻烦——从外部重启这个screen托管的游戏服务器简直行云流水,但在会话内部由游戏进程触发重启时,脚本总卡壳。核心问题在于当你在gameserver这个screen会话内部执行stop.sh时,screen -r gameserver -X quit会直接终止当前你所在的会话,导致后续的start.sh还没来得及运行就被中断了。
下面给你几个实用的解决方案,按易用性和可靠性排序:
方案一:异步执行启动命令,规避会话终止的中断
创建一个restart.sh脚本,把启动逻辑放到后台异步执行,确保即使当前会话被终止,启动流程也能完整走完:
#!/bin/bash # 异步启动新服务器(sleep 2是给旧进程退出留缓冲时间,可根据实际情况调整) nohup bash -c "sleep 2; screen -L -A -m -d -S gameserver /usr/bin/dotnet /path/to/your/game/server.dll" > /dev/null 2>&1 & # 终止旧的screen会话 screen -r gameserver -X quit
关键逻辑说明:
nohup让后续的bash命令脱离当前终端会话的控制,哪怕当前screen被quit,启动命令依然会在后台执行。sleep 2是为了确保旧游戏进程和screen会话完全退出后再启动新服务,避免端口占用或进程冲突。> /dev/null 2>&1把nohup的输出重定向到空设备,避免生成冗余的nohup.out文件。
方案二:先终止游戏进程,再重启会话(更优雅可靠)
如果不想依赖固定时长的sleep,你可以精准终止dotnet进程,等它完全退出后再重启screen会话:
#!/bin/bash # 终止游戏服务器进程(替换成你的dotnet进程的准确匹配字符串) pkill -f "/usr/bin/dotnet /path/to/your/game/server.dll" # 等待进程完全退出(最多等10秒,可按需调整) wait $! 2>/dev/null || true # 终止旧的screen会话(忽略找不到会话的错误提示) screen -r gameserver -X quit 2>/dev/null # 启动新的服务器会话 screen -L -A -m -d -S gameserver /usr/bin/dotnet /path/to/your/game/server.dll
优势:
- 不需要依赖固定等待时间,而是等待进程真正退出后再执行后续操作,稳定性更高。
2>/dev/null用于屏蔽"找不到会话"之类的非致命错误,避免脚本报错中断。
方案三:先脱离当前会话,再执行重启操作
如果希望在当前会话内触发重启,也可以先把当前shell从screen会话中脱离,再执行停止和启动:
#!/bin/bash # 把当前screen会话放到后台并脱离 screen -d # 终止旧会话 screen -r gameserver -X quit # 启动新会话 screen -L -A -m -d -S gameserver /usr/bin/dotnet /path/to/your/game/server.dll # 可选:重新连接到新的服务器会话 screen -r gameserver
注意事项:
这个方案需要当前用户对screen会话有操作权限,脱离会话后后续命令会在原shell环境中执行,更适合手动触发重启的场景。
最后别忘了给脚本加上执行权限:chmod +x restart.sh,之后让游戏进程调用这个restart.sh即可完成内部重启。
内容的提问来源于stack exchange,提问作者Jacob
相关产品推荐
相关产品推荐

