最近在写一个监控服务程序,通过交叉监控来监控我们的线上服务。比如我有两台服务器分别为A和B,在A上部署监控程序来监控服务器B,在B上部署监控程序来部署A.由于监控服务要严格按照我们自定制的业务需求来监控,所有监控服务需要自己实现并部署在后台一直运行。所以我就选择了比较简单的nohup命令,比较轻量也很容易部署。
当用户logout、网络中断和断开连接时,中断会接收到HUP(hangup)信号从而关闭其所有运行的子进程。所以我们解决该问题有两种方式:
nohup ping www.brianlv.com &
tail -f nohup.out
看到的结果如下图所示:
毫无疑问nohup通过忽略HUP信号来避免进程中途中断,如果我们换一个角度思考问题,假设我们的进程不属于接受HUP信号的终端子进程那么自然而然就不会接受到HUP信号。可以通过setsid来设置它的父进程为1并不是当前终端的子进程。
无论是nohup还是setsid都是一般性的解决方案。除了nohup和setsid还有disown和screen,disown 能帮助我们事后补救当前已经在运行的作业,而screen主要用在大批量操作。如果我们没有添加任何东西就运行命令了,那么这时候如何避免HUP信号呢?那就是用disown。
cp -r testLargeFile largeFile &
[1] 4825
jobs
[1]+ Running cp -i -r testLargeFile largeFile &
disown -h %1
ps -ef |grep largeFile
root 4825 968 1 09:46 pts/4 00:00:00 cp -i -r testLargeFile largeFile
root 4853 968 0 09:46 pts/4 00:00:00 grep largeFile
如果提交命令时未使用“&”将命令放入后台运行,可使用 CTRL-z 和“bg”将其放入后台,再使用“disown”
cp -r testLargeFile largeFile2
[1]+ Stopped cp -i -r testLargeFile largeFile2
bg %1
[1]+ cp -i -r testLargeFile largeFile2 &
jobs
[1]+ Running cp -i -r testLargeFile largeFile2 &
disown -h %1
ps -ef |grep largeFile2
root 5790 5577 1 10:04 pts/3 00:00:00 cp -i -r testLargeFile largeFile2
root 5824 5577 0 10:05 pts/3 00:00:00 grep largeFile2
正如我们之前提到一样,如果我们不指定重定向输出的话。那么它会生成一个nohup.out文件。比如说我们再程序里面有print或者类似的输出流都会写入到nohup.out里面。那么这对于我们调试和开发而言很不方便,特别是有的系统本省重写了类似Log系统。如果指定输出重定向文件的话,在nohup运行时每次都是覆盖。我们先来看一下简单的命令:
nohup command > test.log 2>&1 &
1代表了标准输出即(stdout) 2代表了标准错误输出即(stderr) 上面的脚本意思是:将command输出重定向到test.Log文件中,即输出内容不打印在屏幕上并且这种写法也算是比较高效的。如果你不想重定向到任何文件包括nohup.out,想使用自己的Log系统可以这样设置。
nohup command > /dev/null 2>&1 &