[root@cheung ~]# cat /ping.sh
#!/bin/sh
ping www.baidu.com
脚本程序后台运行只需要加上一个&在最后,但有一个问题ssh窗口关闭或网络断开,此后台程序也会停止运行。
原因:
当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其所有子进程。
解决办法:
让进程忽略HUP信号或者将对应脚本程序设置为不属于此终端的子进程。
nohup
nohup用途就是让提交的命令忽略HUP信号。用法为将nohup加到命令之前,当然为了让其后台运行也需要在命令行最后添加上&。由于此命令会将标准输出和标准错误默认重写向到nohup.out中,所以可以在命令之后添加上">filename 2>&1",这里我把输出重新定向到/ping.txt文件中。
nohup /ping.sh >/ping.txt 2>&1 &
setsid
setsid用途是让提交的命令归属一个新会话。用法也是添加到命令之前。
首先我们对比下进程父ID(PPID),首先是直接执行脚本时情况:
/ping.sh &
[root@cheung ~]# ps -ef |grep ping
root 2149 2022 0 19:12 pts/2 00:00:00 /bin/sh ./ping.sh
root 2150 2149 0 19:12 pts/2 00:00:00 ping www.baidu.com
root 2154 2053 0 19:12 pts/1 00:00:00 grep ping
然后是使用nohup时情况:
nohup /ping.sh >ping.txt 2>&1 &
[root@cheung ~]# ps -ef |grep ping
root 2160 2022 0 19:13 pts/2 00:00:00 /bin/sh ./ping.sh
root 2161 2160 0 19:13 pts/2 00:00:00 ping www.baidu.com
root 2163 2053 0 19:13 pts/1 00:00:00 grep ping
最后是使用setsid时情况:
setsid /ping.sh >ping.txt 2>&1 &
[root@cheung ~]# ps -ef |grep ping
root 2175 1 0 19:15 ? 00:00:00 /bin/sh /ping.sh
root 2176 2175 0 19:15 ? 00:00:00 ping www.baidu.com
root 2178 2053 0 19:15 pts/1 00:00:00 grep ping
通过对比可看出使用setsid提交的命令父进程ID为1,并不是当前终端进程ID。
disown
如果我们未加任何处理就已经提交了命令,可使用disown补救。
提交的命令已经用了&放入后台运行,直接使用disown
/ping.sh &
[root@cheung ~]# jobs -l
[1]+ 2227 Running /ping.sh &
[root@cheung ~]# disown -h %1
忽略jobspec为1的作业
提交的命令没有使用&放入后台运行,使用CTRL-z暂停挂后台和bg将其放入后台运行,再使用disown
/ping.sh
[1]+ Stopped /ping.sh
[root@cheung ~]# bg %1
[root@cheung ~]# jobs -l
[1]+ 2243 Running ./ping.sh &
[root@cheung ~]# disown -h %1
需要注意的是,当使用过 disown 之后,会将把目标作业从作业列表中移除,我们将不能再使用jobs来查看它,但是依然能够用ps -ef查找到它。
jobs查看当前作业一般接-l,用于显示其作业号。bg %作业号,将作业在后台运行。fg %作业号,将作业在前面处理。CTRL-z,将当前程序挂起。