Linux进程在后台可靠地运行。

1.场景需求场景:如果一个命令只是临时需要长时间运行,那么保证它在后台稳定运行最简单的方法是什么?hangup这个名字的由来在早期版本的Unix中,每个终端都会通过modem与系统进行通信。当用户注销时,调制解调器挂断电话。同样,当调制解调器断开连接时,它会向终端发送一个挂断信号,通知它关闭所有子进程。解决方案:我们知道,当用户注销或网络断开时,终端会收到HUP(hangup)信号来关闭它的所有子进程。所以解决这个问题有两种方法:要么让进程忽略HUP信号,要么让进程在新的会话中运行,成为不属于这个终端的子进程。
2.nohup订购nohup无疑是我们首先想到的。顾名思义,nohup的目的就是让提交的命令忽略挂断信号。我们先来看看nohup的帮助信息:
NOHUP(1)用户命令NOHUP(1) NAMEnohup -运行不受挂起影响的命令,输出到非tty SYNOPSISnohup命令[ARG].nohup选项描述运行命令,忽略挂断信号。-Help显示此帮助并退出-Version输出版本信息并退出可以看出nohup的使用非常方便,只需在要处理的命令前添加nohup,标准输出和标准错误的默认会重定向到nohup.out文件。一般情况下,我们可以在末尾加上“”,以便同时在后台运行命令,或者使用“filename 21”来更改默认的重定向文件名。
~]# nohup ping www.ibm.com[1]3059 nohup :将输出附加到“nohup . out”~]# PS-ef | grep 3059 root 3059 984 0 21:06 pts/00:00 ping www.ibm.com root 3067 984 0 21336006 pts/3 00336000 grep 30593。SetSID命令noHUP通过忽略HUP信号无疑可以避免我们的进程被中断,但是如果换个角度思考,如果我们的进程不属于接收HUP信号的终端的子进程。Setsid可以帮助我们做到这一点。我们先来看看setsid的帮助信息:
SETSID(8) Linux程序员手册SETSID(8) NAMEsetsid -在新会话中运行程序SYNOPSISsetsid程序[ arg.] Description sid在新的会话中运行程序。可以看出,setsid的使用也非常方便,只需在要处理的命令前添加setsid即可。
~]# setsid ping www . IBM . com ~]# PS-ef | grep www . IBM . com root 31094 1 0 07:28 00:00 ping www . IBM . com root 31102 29217 0 07:29 pts/00:0:00 www.ibm.com值得注意的是,在上面的例子中,我们的进程ID(PID)是3100将这个例子与nohup例子中的父ID进行比较。
4.这是关于subshell的另一个技巧。我们知道在“()”中包含一个或多个名字可以使这些命令在子shell中运行,从而扩展出许多有趣的功能,我们现在要讨论的就是其中之一。当我们把“”放入“()”时,会发现提交的作业不在作业列表中,即无法通过作业查看。我们来看看为什么可以这样避免HUP信号的影响。
~]#(ping www.ibm.com)~]# PS-ef | grep www . IBM . com root 16270 1 0 14:13 pts/4 00:0:00 ping www . IBM . com root 16278 15362 0 14:13 pts/00:00 grep www.ibm.com从上面的例子可以看出,新提交的进程的父ID(PPID)所以不属于当前终端的子进程,所以不会受到当前终端的HUP信号的影响。
5.disown场景:我们已经知道,如果事先在命令前加上nohup或者setsid,就可以避免hup信号的影响。但是如果我们已经提交了没有经过任何处理的命令,如何补救才能避免HUP信号的影响呢?解决方法:此时添加nohup或setsid已经来不及了,只能通过作业调度和disown来解决问题。我们来看看disown的帮助信息:
否认[-ar][-h][工作规范.]如果没有选项,每个jobspec都将从活动工单表中删除。如果给定了-h选项,每个jobspec不会从表中删除,但会被标记,以便在shell收到SIGHUP时不会将SIGHUP发送给作业。如果不存在jobspec,并且既没有提供-a选项也没有提供-r选项,则使用当前作业。如果没有提供jobspec,则-a选项意味着删除或标记所有作业;不带jobspec参数的-r选项将操作限制为正在运行的作业。返回值为0减去jobspec未指定有效作业。可以看出,我们可以通过以下方法来实现我们的目标。CTRL-z的灵活使用在我们的日常工作中,可以使用CTRL-z在后台暂停当前进程并执行一些其他操作,然后使用fg将暂停的进程放回前台(或者bg将暂停的进程放在后台)继续运行。这样就可以在一个终端中灵活切换运行多个任务,在调试代码的时候特别有用。因为当代码编辑器悬浮到后台再放回去时,光标定位仍然停留在上次悬浮的位置,避免了重新定位的麻烦。使用dissolve-h job spec使作业忽略HUP信号。Disown -ah用于使所有作业忽略HUP信号。使用dissolve-RH使正在运行的作业忽略HUP信号。需要注意的是,使用disown后,目标作业将从作业列表中删除。我们已经不能用jobs来查看了,但是用ps -ef还是可以找到的。但是还有一个问题。这种方法的操作对象是作业。如果我们在命令的末尾加上” “,使之成为一个作业,并在后台运行,那么一切都会好的。我们可以通过jobs命令获得所有作业的列表。但是如果当前命令不是作为作业运行的,我们如何获得它的作业号呢?答案是用CTRL-z(按住Z键的同时按住CTRL键)!CTRL-z的目的是暂停当前进程,那么我们可以用jobs命令查询它的作业号,然后用bg jobspec放到后台继续运行。请注意,如果挂起会影响当前进程的运行结果,则应谨慎使用此方法。Disown示例1(如果在提交命令时已经用“”将命令放入后台,可以直接使用“disown”)
build]# CP-r test large file large file[1]4825 build]# jobs[1]正在运行CP-I-r test large file large file build]# disown-h uild]# PS-ef | grep large file root 4825 968 1 09:46 pts/4 00:00:00 CP-I-r test large file large file large file root 4853 968 0 093:46 pts/0033:46 pts
build]# CP-r test large file large file 2[1]已停止CP-I-r test large file large file 2 build]# BG % 1[1]CP-I-r test large file 2 build]# jobs[1]正在运行CP-I-r test large file large file 2 build]# disown-h uild]# PS-ef | grep large file 2 root 5790 5577 1 10:04 pts/003:00 CP-I-r testScreen场景:我们已经知道如何保护进程不受HUP信号的影响,但是如果有大量这样的命令需要在稳定的后台运行,如何避免对每一个解决方案的影响:这个时候,最方便的方法就是screen。简单来说,screen提供了ANSI/VT100终端模拟器,使其能够在一个真实终端下运行多个全屏伪终端。屏幕参数多,功能强大。这里只介绍一下它的常用功能,简单分析一下为什么使用screen可以避免HUP信号的影响。我们先来看看screen的帮助信息:
SCREEN(1) SCREEN(1) NAMEscreen -带有VT100/ANSI终端仿真概要的屏幕管理器SCREEN[-options][cmd[args]]SCREEN-r[[PID。tty。host]]screen-r session owner/[[PID。tty。host]] DESCRIPTIONScreen是一个全屏窗口管理器,它在几个进程(通常是交互式shells)之间复用一个physicalterminal。每个虚拟终端提供DEC VT100终端的功能,此外,还提供ISO 6429 (ECMA48,ANSI X3.64)和ISO 2022标准的几种控制功能(例如插入/删除行和支持多字符集)。每个虚拟终端都有一个回滚历史缓冲区和一个复制粘贴机制,允许在窗口之间移动文本区域。方便地使用screen,有几个常用的选项:使用screen -dmS session name在断开模式下建立会话(并指定其会话名)。使用screen -list列出所有会话。使用screen -r会话名称重新连接指定的会话。使用快捷键CTRL-a d暂时断开当前会话。屏幕示例
~]# screen -dmS乌鲁木齐~]# screen-list有一个: 12842的屏幕。Urumchi(分离的)1个插座,输入/tmp/screens/S-root。~]# Screen -r Urumchi当我们用“-r”连接屏幕会话时,在这个伪终端中我们可以为所欲为。我们不必再担心HUP信号对我们的进程的影响,也不必在每个命令前添加“nohup”或“setsid”。这是为什么呢?让我看看下面两个例子。1.不使用屏幕时新流程的流程树
~] #平www.google.com[1]9499 ~]# pstree-h9499init–xvnc -acpid–atd–2 *[sendmail]–sshd–sshd-不使用screen时,我们所在的bash是sshd的一个子进程。当ssh断开时,HUP信号自然会影响它下面的所有子进程(包括我们新建立的ping进程)。2.使用屏幕后新流程的流程树
~]# screen -r乌鲁木齐~]#平www.ibm.com[1]9488[root @ pvcent 107 ~]# p tree-h 9488initxvnc acpid atd screenbashping 2*[sendmail]不过用screen的时候就不一样了。此时bash是screen的子进程,screen是init的子进程(PID为1)。那么当ssh断开时,HUP信号自然不会影响screen下的子进程。
7.总结现在已经介绍了几种方法,可以根据不同的场景选择不同的方案。Nohup/setsid对于临时需求来说无疑是最方便的方法。disown可以帮助我们补救已经在运行的作业,而screen是批处理操作的最佳选择。

其他教程

h5页面搭建(可视化H5页面设计与制作)

2022-8-28 3:08:15

其他教程

数千万被赞的“车库摇摇”被封杀,短暂的柔情和断臂求生的Tik Tok。

2022-8-28 3:10:31

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索