Linux脚本求助:启动ICAtariControllerServer与游戏客户端,客户端退出时终止服务器
问题描述
我是Linux新手,正在编写脚本以同时启动服务器ICAtariControllerServer和游戏客户端Circus_Interstellar,希望服务器后台运行、游戏前台运行,且无论客户端以何种方式退出(点击游戏退出按钮、崩溃、终端退出等),服务器都能随之终止。目前脚本可成功启动两者,但客户端退出后服务器仍在运行,以下是我使用的脚本代码:
# Function to start the server process start_server() { ./server/ICAtariControllerServer & server_pid=$! # disown } # Function to start the client process start_client() { ./Circus_Interstellar sleep 5 & client_pid=$! # disown } # Function to kill the server process kill_server() { kill -9 "$1" } # Function to kill the client process kill_client() { kill -9 "$1" } # Trap signals and clean up processes trap "kill_client $client_pid; kill_server $server_pid; exit" SIGINT SIGTERM EXIT # Main script logic start_server start_client # Wait for the client process to exit wait $client_pid
问题分析
- 客户端PID获取错误:原
start_client函数中,前台运行的客户端进程PID未被记录,反而把多余的sleep 5进程PID当成了客户端PID,导致后续wait和trap无法正确追踪客户端状态。 - Trap变量展开时机错误:设置
trap时$client_pid和$server_pid还未赋值,最终trap里的命令会变成空执行,完全起不到清理作用。 - 强制终止过于粗暴:直接使用
kill -9(SIGKILL)会跳过进程资源清理步骤,优先使用默认的SIGTERM让进程优雅退出更合理。 - 冗余代码干扰:
start_client里的sleep 5完全没必要,反而打乱了PID的正确获取逻辑。
修正后的脚本
# 启动服务器并记录PID start_server() { ./server/ICAtariControllerServer & server_pid=$! } # 启动客户端并记录PID,同时保持前台交互 start_client() { ./Circus_Interstellar & client_pid=$! fg %"$client_pid" } # 优先优雅终止服务器,失败则强制终止 kill_server() { if [ -n "$1" ] && kill -0 "$1" 2>/dev/null; then kill "$1" sleep 1 if kill -0 "$1" 2>/dev/null; then kill -9 "$1" fi fi } # 主执行逻辑 start_server start_client # 等待客户端进程完全退出 wait "$client_pid" # 客户端退出后终止服务器 kill_server "$server_pid"
关键修改说明
- 正确追踪客户端PID:先将客户端后台启动获取PID,再用
fg切回前台,既保证了游戏的交互性,又能准确记录客户端进程ID。 - 简化流程逻辑:去掉复杂的
trap配置,直接在客户端进程退出后执行服务器终止命令,确保无论客户端以何种方式退出,脚本都会触发服务器清理步骤。 - 优雅终止进程:先尝试用SIGTERM让服务器自行清理资源,等待1秒后如果进程仍未退出,再用SIGKILL强制终止,避免资源泄漏。
- 移除冗余代码:删掉无用的
sleep进程和未启用的disown注释,精简脚本逻辑。
内容的提问来源于stack exchange,提问作者Roastedzerg
相关产品推荐
相关产品推荐

