前言
对于linux运维,我们都是使用ssh登录到服务器,如果我们运行的任务需要很长时间或不间断运行,在我们直接关闭终端窗口或网络不稳定的情况下,任务就会中断,当然这只对于普通程序,不包括如mysqld,httpd这样的守护进程。
原因分析:
[root@DigMouse ~]# ping 51osos.com > /dev/null & [1] 13678 [root@DigMouse ~]# pstree -H 13678 init-+-NetworkManager |-sshd---sshd---bash-+-ping | `-pstree
当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其所有子进程。
从上面的例子大家可以看出当前我们所处的 bash 是 sshd 的子进程,当 ssh 断开连接时,HUP 信号会影响到它下面的所有子进程,包括ping进程。
解决思路:
1.让进程运行在新的session(会话)里即不属于此终端的子进程。
2.可以让进程忽略HUP信号
具体实现方法如下
nohup命令
功能:不挂断地运行命令,忽略HUP信号。
语法:nohup command &
实例:
解决方法:
1.nohup命令
功能:不挂断地运行命令,忽略HUP信号。
语法:nohup command &
实例:
nohup ping 51osos.com > /dev/null & // [1] 13683 //nohup: ignoring input and redirecting stderr to stdout ls // Desktop Downloads nohup.out // Documents Music Public Videos cat nohup.out // PING cd447.gotoip.net (122.225.57.246) 56(84) bytes of data. // 64 bytes from 122.225.57.246: icmp_seq=1 ttl=56 time=48.6 ms // 64 bytes from 122.225.57.246: icmp_seq=2 ttl=56 time=47.8 ms // 64 bytes from 122.225.57.246: icmp_seq=3 ttl=56 time=49.9 ms // 64 bytes from 122.225.57.246: icmp_seq=4 ttl=56 time=49.5 ms ps -ef | grep ping // root 13683 13655 0 09:33 pts/0 00:00:00 ping 51osos.com // root 13687 13655 0 09:36 pts/0 00:00:00 grep ping
关闭此终端,打开另一个终端使用ps命令,仍然可以查看到ping进程。
无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。
如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。
nohup command > command.out 2>&1 &
上面的例子中nohup command输出的内容输出到了command.out文件中,错误内容输出到了标准输出。
setsid命令
功能:run a program in a new session在新的会话中运行程序
实例:
setsid ping 51osos.com > /dev/null ps -ef | grep ping // root 13696 1 0 09:45 ? 00:00:00 ping 51osos.com // root 13698 13655 0 09:46 pts/0 00:00:00 grep ping
从上例可以看出ping进程的PID是13696,进程的父ID(PPID)是init而不是当前终端的进程 ID,可与nohup比较。
将&也放入()内执行命令
将一个或多个命名包含在“()”中就能让这些命令在子 shell 中运行
(ping 51osos.com > /dev/null &) ps -ef | grep ping // root 13702 1 0 09:50 pts/0 00:00:00 ping 51osos.com // root 13704 13655 0 09:50 pts/0 00:00:00 grep ping
进程的父ID(PPID)是init而不是当前终端的进程 ID,因而关闭终端无任何影响。
disown命令
用disown -h jobspec
来使某个作业忽略HUP信号。 用disown -ah
来使所有的作业都忽略HUP信号。
用disown -rh
来使正在运行的作业忽略HUP信号。
当使用过 disown 之后,会将把目标作业从作业列表中移除,我们将不能再使用jobs
来查看它,但是依然能够用ps -ef
查找到它。
但是还有一个问题,这种方法的操作对象是作业,如果我们在运行命令时在结尾加了&
来使它成为一个作业并在后台运行,那么就万事大吉了。
我们可以通过jobs命令来得到所有作业的列表。但是如果并没有把当前命令作为作业来运行,如何才能得到它的作业号呢?答案就是用 CTRL-z
(按住Ctrl键的同时按住z键)了!
CTRL-z 的用途就是将当前进程挂起(Suspend),然后我们就可以用jobs命令来查询它的作业号,再用bg jobspec
来将它放入后台并继续运行。
需要注意的是,如果挂起会影响当前进程的运行结果,请慎用此方法。
ping 51osos.com > /dev/null ^Z // [1]+ Stopped ping 51osos.com > /dev/null jobs // [1]+ Stopped ping 51osos.com > /dev/null bg %1 // [1]+ ping 51osos.com > /dev/null & jobs // [1]+ Running ping 51osos.com > /dev/null & disown -h %1 ps -ef | grep ping // root 13716 13655 0 09:59 pts/0 00:00:00 ping 51osos.com // root 13734 13655 0 10:01 pts/0 00:00:00 grep ping
此时jobs还是能看到ping后台任务的。
logout后在另一个终端测试 。
ps -ef | grep ping // root 13716 1 0 09:59 ? 00:00:00 ping 51osos.com // root 13754 13738 0 10:02 pts/1 00:00:00 grep ping
此时Jobs无ping后台任务,PPID变成了1 。
screen命令
安装
yum install screen*
创建一个新的窗口
安装完成后,直接敲命令screen就可以启动它。但是这样启动的screen会话没有名字,实际使用时推荐为每个screen会话取一个名字,方便分辨:
screen -S yumefx
screen启动后,会创建第一个窗口,也就是窗口No. 0,并在其中打开一个系统默认的shell,一般都会是bash。
所以你敲入命令screen之后,会立刻又返回到命令提示符,仿佛什么也没有发生似的,其实你已经进入Screen的世界了。
当然,也可以在screen命令之后加入你喜欢的参数,使之直接打开你指定的程序,例如:
screen vi yumefx.txt
screen创建一个执行vi yumefx.txt
的单窗口会话,退出vi 将退出该窗口/会话。
查看窗口和窗口名称
打开多个窗口后,可以使用快捷键Ctrl+a w
列出当前所有窗口。
如果使用文本终端,这个列表会列在屏幕左下角,如果使用X环境下的终端模拟器,这个列表会列在标题栏里。窗口列表的样子一般是这样:
0$ bash 1-$ bash 2*$ bash
这个例子中我开启了三个窗口,其中*号表示当前位于窗口2,-号表示上一次切换窗口时位于窗口1。
Screen默认会为窗口命名为编号和窗口中运行程序名的组合,上面的例子中窗口都是默认名字。
练习了上面查看窗口的方法,你可能就希望各个窗口可以有不同的名字以方便区分了。
可以使用快捷键Ctrl+a A
来为当前窗口重命名,按下快捷键后,Screen会允许你为当前窗口输入新的名字,回车确认。
会话分离与恢复
你可以不中断screen窗口中程序的运行而暂时断开(detach)screen会话,并在随后时间重新连接(attach)该会话,重新控制各窗口中运行的程序。
例如,我们打开一个screen窗口编辑/tmp/yumefx.txt文件:
screen vi /tmp/yumefx.txt
之后我们想暂时退出做点别的事情,比如出去散散步,那么在screen窗口键入Ctrl+a d
,Screen会中断会话:
半个小时之后回来了,找到该screen会话:
screen -ls // There is a screen on: // 12865.pts-0.TS-DEV (Detached) // 1 Socket in /var/run/screen/S-root. screen -r 12865
重新连接会话,一切都在。
当然,如果你在另一台机器上没有分离一个Screen会话,就无从恢复会话了。
这时可以使用下面命令强制将这个会话从它所在的终端分离,转移到新的终端上来:
screen -ls // There is a screen on: // 5011.yume (Attached) // 1 Socket in /var/run/screen/S-root. screen -r 5011 // There is a screen on: // 5011.yume (Attached) // There is no screen to be resume matching 5011. screen -d // [5011.yume detached.] screen -r 5011
清除dead 会话
如果由于某种原因其中一个会话死掉了(例如人为杀掉该会话),这时screen -list
会显示该会话为dead状态。
使用screen -wipe
命令清除该会话:
screen -ls // There is a screen on: // 5011.yume (Dead ???) screen -wipe // There is a screen on: // 5011.yume (Removed) // 1 Socked wiped out.
关闭或杀死窗口
正常情况下,当你退出一个窗口中最后一个程序(通常是bash)后,这个窗口就关闭了。
另一个关闭窗口的方法是使用Ctrl+a k
,这个快捷键会杀死当前的窗口,同时也将杀死这个窗口中正在运行的进程。
如果一个Screen会话中最后一个窗口被关闭了,那么整个Screen会话也就退出了,screen进程会被终止。
除了依次退出/杀死当前Screen会话中所有窗口这种方法之外,还可以使用快捷键Ctrl+a :
,然后输入quit命令退出Screen会话。
需要注意的是,这样退出会杀死所有窗口并退出其中运行的所有程序。其实Ctrl+a :
这个快捷键允许用户直接输入的命令有很多,包括分屏可以输入split等,这也是实现Screen功能的一个途径,不过个人认为还是快捷键比较方便些。
看到最后,我还是用screen吧。
照自己的意愿一息尚存,也好过听从别人的安排,虚张声势的过着浅薄生活。
《我要快乐,不必正常》——珍妮特·温特森
评论
Hmm it appears like your website ate my first comment (it was super long) so I guess I’ll just sum it up what I submitted and say, I’m thoroughly enjoying your blog. I too am an aspiring blog blogger but I’m still new to the whole thing. Do you have any tips and hints for newbie blog writers? I’d really appreciate it.
https://www.einco.es/942-estuches/95277-lagart-329272-329272-caja-de-lapices-estuche-suave-colores-surtidos-8430173292728.html
What is Boostaro? Boostaro revolutionizes romantic performance enhancement through its reliance on the wisdom of natural ingredients
https://youtu.be/hnWLgZb0Iww
I really appreciate this post. I’ve been looking everywhere for this! Thank goodness I found it on Bing. You have made my day! Thank you again
https://youtu.be/7IDhVlV6-38
Hey There. I found your blog using msn. This is a very well written article. I’ll make sure to bookmark it and come back to read more of your useful information. Thanks for the post. I will certainly return.
https://youtu.be/-jWAH_gWinY
I’ve been surfing on-line greater than 3 hours today, yet I by no means discovered any interesting article like yours. It?¦s lovely worth sufficient for me. In my view, if all site owners and bloggers made just right content as you probably did, the net will likely be much more helpful than ever before.
https://youtu.be/8t6cCMoxSDs
Great post. I was checking constantly this blog and I am impressed! Very useful info specially the last part 🙂 I care for such info a lot. I was seeking this certain information for a very long time. Thank you and good luck.
https://youtu.be/NU00wZLJW-E