部署在服务器上的项目一直运行
当将程序部署到服务器运行时,总是会出现 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
如果该文件内容没有再动态增加。说明停止成功。