You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:01:04