22.命令脱离终端会话运行
#命令脱离终端会话运行
什么意思呢?打开一个终端,用户命令行启动一个程序在后台运行,而一旦终端会话断开的同时,后台运行的程序也就停止了。
比如运行个go
程序:
package main
import (
"fmt"
"os"
"time"
)
func main() {
pid := os.Getpid()
fmt.Println(pid) // 打印进程id
time.Sleep(1000 * time.Second) // 休眠1000秒,保持程序一直运行
}
$ go run main.go & // 以后台方式,运行起来
[1] 50768
然后打开一个新的终端,来观察这个程序的状态,如下:
新终端窗口
$ ps aux | grep 50768
dev 50768 0.0 0.0 4973164 5712 s010 SN 2:20AM 0:00.01 /var/folders/9q/xmn0xglx2vvbcvvd91_c6zgw0000gq/T/go-build657799047/b001/exe/main
提示
可以看到进程号是在的,很是说明程序还在内存当中运行着。
而当我们强制关闭原来运行的终端时,在新的终端中:
新的终端
$ ps aux | grep 50768
结果是在内存中没有一个进程号为50768,说明这个后台程序已经随着终端的断开而退出。这是因为会话一结束,
linux
会自动 向由这个终端会话运行的全部后台程序发送1 SIGHUP
信号,来终止全部(守护进程的程序不算)的程序。那有没有一直保持程序的运行, 哪怕终端的连接会话关闭了,程序也能一直保持运行?可以的?推荐做法1:
nohup
方式运行命令字面上的意思,用这种方式运行后台程序,
terminal
会话终端后,linux
不会给这个程序发送
SIGHUB信号,自然就没有 退出的情况发生。如打开一个终端,使用
nohup方式运行
go`程序,然后退出这个终端,如下: 临时终端$ nohup go run main.go &
[1] 12633
appending output to nohup.out
而在新的终端,依然还是可以看见这个进程号
用于观察的终端
ps aux | grep 12633
wuchuheng 12720 0.0 0.0 408103296 1264 s009 S+ 3:32PM 0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox 12633
wuchuheng 12633 0.0 0.5 9129872 41664 s002 SN 3:28PM 0:00.30 go run main.go说明用这程度方式,进程是真的脱离了终端会话独自在后台运行。
tip
如果不想要输出日志,那么可以
nohup go run main.go > /dev/null 2>&1
系统自启动方式
把启动命令写在/etc/rc.local
, linux
启动时会自动运行这个文件上的命令。 原因是这个是系统启动级别的运行,运行这个命令是系统而不是用户,如果用户不是超级管理员
那这个进程,用户是无法杀死的。
可行但不推荐的方法-定时任务
定时任务可以运行,但给人的感觉不是很好理解,我要启动一个常驻后台的程序,不能直接启动要加入定时才行,有点费解。