nohup-长期运行进程

我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却由于网络的不稳定导致任务中途失败。

解决办法:
当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其所有子进程。因此,我们的解决办法就有两种:要么让进程忽略 HUP 信号,要么让进程运行在新的会话里从而成为不属于此终端的子进程。


模拟一个断开的会话,看一下前台进程是否还会正常运行:

[root@node1 ~]# cat b.sh 
#!/bin/bash
for((;;)) do
        sleep 1
        echo "no" >> /tmp/b.txt
done


第一个会话:
[root@node1 ~]# bash b.sh   #执行脚本,会占据整个当前会话页面

新打开一个会话:
[root@node1 ~]# ps -ef | grep b.sh
root      34693  28170  0 11:32 pts/0    00:00:00 bash b.sh
...
[root@node1 ~]# kill -1 34693    #模拟第一个会话断开的情况,发送SIGHUP信号

再次切换至第一个会话:
[root@node1 ~]# bash b.sh
Hangup                   #已经断线
[root@node1 ~]#


nohup

nohup - run a command immune to hangups, with output to a non-tty

运行一个忽略hangups(SIGHUP)影响的命令,输出到一个非tty

格式:
nohup COMMAND [ARG]...

示例:

[root@node1 ~]# nohup bash b.sh          #占据当前会话,使得当前会话不可执行其它命令
nohup: ignoring input and appending output to ‘nohup.out’   #如不指定日志输出位置,默认输出至当前目录下的nohup.out文件中。


重新打开一个会话:
[root@node1 ~]# ps -ef | grep b.sh
root      25973  16490  0 09:56 pts/1    00:00:00 bash b.sh
[root@node1 ~]# kill -1 25973     #向进程发送SIGHUP信号,nohup进程还在运行。关闭上一个session会话,效果和kill -1效果一样
[root@node1 ~]# 

nohup将标准输出和标准错误缺省会被重定向到nohup.out文件中。一般我们可在结尾加上&来将命令同时放入后台运行,也可用>xxx.log 2>&1(将标准输出和标准错误输出至指定的文件中)来更改缺省的重定向文件名。

setsid

setsid - run a program in a new session

在一个新的会话中运行一个程序。

格式:
setsid program [arg...]

示例:

[root@node1 ~]# setsid bash b.sh      #使用setsid来代替nohup
[root@node1 ~]# jobs                  #后台无法查看
[root@node1 ~]# ps -ef | grep c.sh    #ps查找其进程,可以看到PID是43019,但PPID确为1(systemd)
root      43593      1  0 14:15 ?        00:00:00 bash b.sh
root      44473  43385  0 14:22 pts/1    00:00:00 grep --color=auto b.sh

[root@node1 ~]# pstree -H 43593 -p
systemd(1)─┬─NetworkManager(3403)─┬─{NetworkManager}(3543)
           │                      └─{NetworkManager}(3551)
           ├─agetty(3528)
           ├─auditd(2802)───{auditd}(2806)
           ├─bash(43593)───sleep(44564)             #因为父进程是1,不属于某个终端的子进程,所以也就无法接收到HUP信号。但是不能使用专门指定这个此进程发送HUP信号,这样是会中断的。
           ├─chronyd(3472)
           ├─crond(3490)
           ...
           ├─sshd(4154)───sshd(16488)─┬─bash(36542)───less(40656)
           │                          ├─bash(42726)
           │                          └─bash(43385)───pstree(44565)
           ...



同样的,在shell也有一种可以使用进程的PPID改成1的方法,使用()括起来并加上&,也和setsid效果一样。

[root@node1 ~]# (bash b.sh &)    #后台执行命令
[root@node1 ~]# jobs             #jobs无法查看
[root@node1 ~]# ps -ef | grep b.sh
root      45631      1  0 14:30 pts/1    00:00:00 bash b.sh       #PPID为1
root      45706  43385  0 14:31 pts/1    00:00:00 grep --color=auto b.sh
[root@node1 ~]# kill -1 45631       #向进程发送HUP信号
[root@node1 ~]# ps -ef | grep b.sh  #进程被中断
root      45784  43385  0 14:31 pts/1    00:00:00 grep --color=auto b.sh
[root@node1 ~]# 


jobs:

显示当前会话下后台任务列表。也就是说,如果当命令切换至后台和想要显示后台有哪些进程不是同一个会话,那么将查不出来有哪些后台进程。

格式:
jobs [option]

常用选项:

  • -l:列出进程ID及其它信息
  • -p:仅列出PID
  • -n:仅列出自从上次输出了状态变化提示。run -> stop
  • -r:显示运行中的进程
  • -s:显示停止的进程


fg:

将命令从后台作业提到前台终端运行。使用格式fg 任务号。任务号是由jobs命令获取的第一列。


bg:

使用格式bg 任务号。想要使用bg命令,首先对前台命令ctrl+z下放置后台成stop模式后,在对其使用bg命令才能像一开始在命令后添加&一样后台运行。需要注意的是,如果挂起会影响到当前进程执行的结果,请慎用ctrl+zbg


示例:

[root@node1 ~]# bash b.sh      #ctrl+z挂起进程至后台
^Z
[1]+  Stopped                 bash b.sh
[root@node1 ~]# jobs
[1]+  Stopped                 bash b.sh
[root@node1 ~]# bg 1     #后台继续运行
[1]+ bash b.sh &  
[root@node1 ~]# jobs     #已经运行
[1]+  Running                 bash b.sh &
[root@node1 ~]# 

[root@node1 ~]# bash    #重新打开一个bash
[root@node1 ~]# jobs    #查询后台进程,查询为空,所以jobs只能查询当前会话的后台进程。
[root@node1 ~]# 

[root@node1 ~]# exit   #退出新的bash
exit
[root@node1 ~]# jobs    #查看jobs
[1]+  Running                 bash b.sh &
[root@node1 ~]# fg 1   #调至前台运行
bash b.sh


总结:
nohup是使用进程本身忽略HUP信号从而达到可以后台运行不被意外中断。setsid和shell中的( &)是将进程的父进程改为1,从而达到不受sshd连接的各种情况影响。
jobs,bg,fg三个命令只能在当前的会话终端上执行,一但会话终端意外剥离,就无法在操作。

参考资料:https://www.ibm.com/developerworks/cn/linux/l-cn-nohup/index.html

转载于:https://www.cnblogs.com/dance-walter/p/10314402.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值