如何让部署在服务器上的项目一直运行

部署在服务器上的项目一直运行

当将程序部署到服务器运行时,总是会出现 Xshell 断开连接后,该程序停止运行的情况。这是因为运行服务的程序是基于 Xshell 打开终端的进程。因此,当终端断开连接,基于该终端运行的程序子进程将全部关闭。如果希望即使终端关闭,程序依旧可以运行则有两种方法可以实现,分别是 nohup 运行程序 和 将程序加入到 systemd 服务。本文介绍 nohup 命令执行方式

利用 nohup在后台运行该程序

nohup (no hangup) 命令,不挂断运行命令,当终端进程退出时,利用 nohup运行的命令会使该程序忽略 HUP 信号。保证程序能够正常运行。HUP信号有些人可能比较陌生,它是在终端被中止的时候向它所关联的进程所发出的信号,进程收到这个信号后就会中止运行。所以如果你不希望进程被这个信号干掉的话,就可以忽略这个信号。而 nohup 命令做的就是这个事情。

安装 nohup 命令

在服务器终端执行以下命令

sudo apt install nohup

ubuntu22.04 发行版好像自带该命令。执行完上述命令之后,查看当前文章的版本号。

nohup --version

使用 nohup 命令

终端显示上述界面表示nohup命令安装成功。基本的语法如下:

$ nohup command arguments
$ nohup options

使用 nohup 启动命令,执行该命令的进程号将不会随着父进程的关闭而接受到 HUP信号。因此,即使终端关闭,该程序还可以一直运行。使用nohup执行命令

$ nohup /usr/bin/[command] argument &

该进程将会被放在后台进行,并且执行该命令输出的 stdout 或者错误日志 stderr 将会被自动放在 nohup.out 文件夹中,该文件夹是自动创建的,如果将信息放入该文件夹,则可以执行以下命令进行重定向进入 myOutput.log 文件

$ nohup /usr/bin/[command] argument > ./myOutput.log

如果想让后台执行的程序重新回到终端,则可以使用 fg 命令,该命令同样可以解决小白第一次使用vim文本编辑器时,不小心按了 ctrl+z 停止了 vim 的程序进行而导致的无法再次进入的问题。回归正题。既然无法通过关闭终端停止该程序,则需要使用 kill 命令杀死该进程。

通过 ps -ef 找到该进程以及进程号

$ ps -ef | grep /[command]
$ kill 进程号

使用 nohup 命令同时跑多个命令

$ nohup bash -c 'myscript1.sh && myscript2.sh && myscript3.sh' &

nohup命令的基本操作演示完毕,通过一个案例测试该命令的基本操作流程

操作 nohup命令

在操作该命令时,实现要创建要给不停运行的脚本 nohupTest.sh。执行以下命令创建执行脚本

$ vim nohupTest.sh

输入如下内容

#!/bin/bash
while True; do
	echo "hello world"
	sleep 1
done

首先测试该内容是否可以运行

$ chmod 755 nohupTest.sh
$ sh nohupTest.sh

得到如图所示内容

将该文本内容输出至 myOutput.log 中,执行一下命令

$ touch myOutput.log
$ sh nohupTest.sh > myOutput.log

此时终端会出现一个光标一直闪烁,说明本应该在终端输出的内容被重定向至 myOutput.log 文件中

按 ctrl+c 停止该命令,再查看 myOutput.log 文件,发现文件中已经写入了很多内容

引入nohup 命令进行操作,首先在后台执行以下命令,(注意:> 会将文件被重定向的文件清空,然后再写入,而 >>是在被重定向的文件原文中进行追加)

$ sh nohupTest.sh > myOutput.log &
$ tail -f myOutput.log

可以观察到 myOutput.log 文件被重写然后添加内容, &告知系统执行某个命令,此时终端会返回一个 pid 号,该号码就是该子进程的身份证。关闭父进程或者通过pid号杀死该进程都会使该命令关闭。如果不执行nohup关闭父进程,myOutput.log中的内容应该不会被改变。反之

$ nohup sh nohupTest.sh > myOutput.log &

关闭此终端,再打开另一个终端

$ tail -f myOutput.log

发现该文件的内容仍然在不断增加(该终端是新的终端)

经过上述操作可以发现,nohup执行命令时,此时子进程的执行与否不再依赖于父进程的存活。注意fg命令只能显示当前终端后台执行的任务,所以新的终端是无法显示的。目前我所知的方法就是通过ps命令找到进程号,然后终止进程。

$ ps -ef | grep sh nohupTest.sh
$ kill [pid]
$ echo $?

如果终端显示的是 0 代表,kill 命令执行成功

查看是否停止

tail -f myOutput.log

如果该文件内容没有再动态增加。说明停止成功。