Linux nohup 用法

时间:2022-05-06
本文章向大家介绍Linux nohup 用法,主要内容包括nohup、disown、nohup 自定制重定向、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

最近在写一个监控服务程序,通过交叉监控来监控我们的线上服务。比如我有两台服务器分别为A和B,在A上部署监控程序来监控服务器B,在B上部署监控程序来部署A.由于监控服务要严格按照我们自定制的业务需求来监控,所有监控服务需要自己实现并部署在后台一直运行。所以我就选择了比较简单的nohup命令,比较轻量也很容易部署。

nohup

当用户logout、网络中断和断开连接时,中断会接收到HUP(hangup)信号从而关闭其所有运行的子进程。所以我们解决该问题有两种方式:

  • 让进程忽略HUP signal。
  • 让进程运行在新的session里,而不再属于终端的子进程。 我们先通过第一种方式即让进程忽略HUP signal来实现后台运行服务。,nohup是一个忽略HUP signal的POSIX命令行,如果nohup没有设置重定向的话,标准输出和标准错误缺省会被重定向到nohup.out的文件中,当然你也可以自定制重定向文件。并且一般在nohup命令后面加入&来表示将命令同时放入后台运行。我们先看一个比较简单的demo:
nohup ping www.brianlv.com &
tail -f nohup.out

看到的结果如下图所示:

毫无疑问nohup通过忽略HUP信号来避免进程中途中断,如果我们换一个角度思考问题,假设我们的进程不属于接受HUP信号的终端子进程那么自然而然就不会接受到HUP信号。可以通过setsid来设置它的父进程为1并不是当前终端的子进程。

disown

无论是nohup还是setsid都是一般性的解决方案。除了nohup和setsid还有disown和screen,disown 能帮助我们事后补救当前已经在运行的作业,而screen主要用在大批量操作。如果我们没有添加任何东西就运行命令了,那么这时候如何避免HUP信号呢?那就是用disown

  • 用disown -h jobspec来使某个作业忽略HUP信号。
  • 用disown -ah 来使所有的作业都忽略HUP信号。
  • 用disown -rh 来使正在运行的作业忽略HUP信号。 运行 disown 之后,会将把目标作业从作业列表中移除,我们将不能再使用jobs来查看它,但是依然能够用ps -ef查找到它。但是还有一个问题,这种方法的操作对象是作业,如果我们在运行命令时在结尾加了”&”来使它成为一个作业并在后台运行,那么就万事大吉了,我们可以通过jobs命令来得到所有作业的列表。但是如果并没有把当前命令作为作业来运行,如何才能得到它的作业号呢?答案就是用 CTRL-z ,CTRL-z 的用途就是将当前进程挂起(Suspend),然后我们就可以用jobs命令来查询它的作业号,再用bg jobspec来将它放入后台并继续运行。需要注意的是,如果挂起会影响当前进程的运行结果.
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 自定制重定向

正如我们之前提到一样,如果我们不指定重定向输出的话。那么它会生成一个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 &