解决关闭终端窗口导致服务挂掉的问题
在使用 ./start.sh
启动服务后,关闭终端窗口却导致服务挂掉,如何确保服务在关闭终端后依然稳定运行。
问题原因分析
在终端中运行 ./start.sh
启动一个服务时,通常该服务作为前台进程运行,并且与当前终端会话紧密关联。关闭终端窗口时,操作系统会向所有与该终端关联的进程发送 SIGHUP
(挂起信号),这会导致进程终止。因此,服务在终端关闭后挂掉,主要是因为其依赖于终端会话的存在。
解决方法
为了确保服务在关闭终端后仍然运行,您可以采用以下几种方法:
- 使用
nohup
命令 - 使用
&
和disown
- 使用
screen
或tmux
工具 - 配置为
systemd
服务
下面将详细介绍每种方法的具体操作步骤和优缺点。
方法一:使用 nohup
命令
nohup
(No Hang Up)命令用于运行不受挂起信号影响的程序。通过 nohup
启动服务,可以确保服务在终端关闭后继续运行。
步骤
-
启动服务并使用
nohup
nohup ./start.sh > output.log 2>&1 &
nohup
:忽略挂起信号。./start.sh
:您的启动脚本。> output.log
:将标准输出重定向到output.log
文件。2>&1
:将标准错误重定向到标准输出。&
:将进程放入后台运行。
-
验证服务是否在后台运行
使用
ps
或pgrep
命令查找进程:ps aux | grep start.sh # 或 pgrep -fl start.sh
优缺点
-
优点
- 简单易用,无需额外安装软件。
- 输出和错误信息可重定向到文件,便于日志管理。
-
缺点
- 无法轻松地重新连接到进程的终端。
- 不适合需要交互的服务。
方法二:使用 &
和 disown
这种方法将进程放入后台运行,并使用 disown
命令将其与当前终端会话脱离,从而防止进程在终端关闭时被终止。
步骤
-
启动服务并放入后台
./start.sh &
-
使用
disown
将进程与终端脱离disown
-
验证服务是否在后台运行
使用
jobs
查看后台作业,或使用ps
命令查找进程:jobs ps aux | grep start.sh
优缺点
-
优点
- 简单快捷。
- 允许将多个进程与终端脱离。
-
缺点
- 需要手动执行
disown
。 - 与
nohup
类似,无法重新连接到进程的终端。
- 需要手动执行
方法三:使用 screen
或 tmux
工具
screen
和 tmux
是强大的终端多路复用器,允许您创建多个独立的终端会话,即使关闭原始终端,服务仍在运行。您可以随时重新连接到这些会话,查看或控制服务。
使用 screen
-
安装
screen
如果尚未安装,可以使用包管理器安装:
# 对于 Debian/Ubuntu 系统 sudo apt-get install screen # 对于 CentOS/RHEL 系统 sudo yum install screen
-
创建一个新的
screen
会话screen -S myservice
-S myservice
:为会话命名为myservice
,便于管理。
-
在
screen
会话中启动服务./start.sh
-
分离
screen
会话按下
Ctrl+A
,然后按D
键,将会话分离,服务将在后台继续运行。 -
重新连接到
screen
会话screen -r myservice
使用 tmux
-
安装
tmux
如果尚未安装,可以使用包管理器安装:
# 对于 Debian/Ubuntu 系统 sudo apt-get install tmux # 对于 CentOS/RHEL 系统 sudo yum install tmux
-
创建一个新的
tmux
会话tmux new -s myservice
-s myservice
:为会话命名为myservice
。
-
在
tmux
会话中启动服务./start.sh
-
分离
tmux
会话按下
Ctrl+B
,然后按D
键,将会话分离,服务将在后台继续运行。 -
重新连接到
tmux
会话tmux attach -t myservice
优缺点
-
优点
- 支持多会话和窗口管理。
- 允许随时重新连接到会话,查看或控制服务。
- 适合需要长期运行并可能需要交互的服务。
-
缺点
- 需要学习基本的
screen
或tmux
命令。 - 占用一定的系统资源。
- 需要学习基本的
方法四:配置为 systemd
服务
systemd
是现代 Linux 发行版中常用的初始化系统和服务管理器。将您的服务配置为 systemd
服务,可以实现自动启动、自动重启、日志管理等高级功能。
步骤
-
创建
systemd
服务文件使用文本编辑器创建一个新的服务文件,例如
/etc/systemd/system/myservice.service
:[Unit] Description=My Custom Service After=network.target [Service] Type=simple ExecStart=/path/to/start.sh Restart=always User=yourusername WorkingDirectory=/path/to/working/directory StandardOutput=file:/var/log/myservice/output.log StandardError=file:/var/log/myservice/error.log [Install] WantedBy=multi-user.target
- 字段说明:
Description
:服务描述。After
:指定服务启动的顺序,此处表示在网络服务启动后再启动。Type
:服务类型,simple
表示简单服务。ExecStart
:启动服务的命令或脚本的完整路径。Restart
:指定服务崩溃后的重启策略,always
表示总是重启。User
:运行服务的用户。WorkingDirectory
:服务的工作目录。StandardOutput
和StandardError
:日志输出路径。
- 字段说明:
-
创建日志目录并设置权限
sudo mkdir -p /var/log/myservice sudo chown yourusername:yourusername /var/log/myservice
-
重新加载
systemd
配置sudo systemctl daemon-reload
-
启动服务
sudo systemctl start myservice
-
设置服务开机自启
sudo systemctl enable myservice
-
检查服务状态
sudo systemctl status myservice
优缺点
-
优点
- 服务可配置性强,支持自动启动、自动重启、日志管理等。
- 与系统集成良好,适用于生产环境。
- 提供丰富的管理命令,如启动、停止、重启、查看状态等。
-
缺点
- 配置文件相对复杂,需要一定的学习成本。
- 需要管理员权限进行配置。
总结
在关闭终端窗口后服务挂掉的问题,主要是由于服务进程与终端会话绑定,关闭终端导致进程接收到挂起信号 (SIGHUP
) 而终止。通过上述四种方法,您可以有效地解决这一问题:
nohup
:适用于简单场景,快速将服务放入后台。&
和disown
:灵活性较高,适用于无需交互的服务。screen
或tmux
:适合需要长期运行且可能需要交互的服务。systemd
服务:适用于生产环境,提供全面的服务管理功能。
根据具体需求和使用场景,选择最适合的方法即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2019-11-22 SpringBoot AOP注解式拦截与方法规则拦截