Linux小技巧1.nohup/setsid/&使用场景:如果只有一个临时命令需要长时间运行,最简单的保证方法是什么它在后台稳定运行吗?我们的解决办法有两种:要么让进程忽略HUP信号,要么让进程在新的会话中运行,成为不属于这个终端的子进程。解决方法:1、nohup只需要在要处理的命令前加上nohup,标准输出和标准错误会默认重定向到nohup.out文件。一般我们可以在末尾加上“&”同时在后台运行命令,也可以使用>filename2>&1来改变默认的重定向文件名。[root@pvcent107~]#nohuppingwww.ibm.com&[1]3059nohup:将输出附加到`nohup.out'[root@pvcent107~]#ps-ef|grep3059root3059984021:06pts/300:00:00pingwww.ibm.comroot3067984021:06pts/300:00:00grep3059[root@pvcent107~]#2。setsidsetsid的使用也很方便,只需要在处理命令前加上setsid即可。[root@pvcent107~]#setsidpingwww.ibm.com[root@pvcent107~]#ps-ef|grepwww.ibm.comroot310941007:28?00:00:00pingwww.ibm.comroot3110229217007:29pts/400:00:00grepwww.ibm.com[root@pvcent107~]#在上面的例子中,我们的进程ID(PID)是31094,其父ID(PPID)为1(是init进程ID),不是当前终端的进程ID。将此示例与nohup示例中的父ID进行比较。3.&在“()”中包含一个或多个名称,使这些命令在子shell中运行。当我们在“()”中也加上“&”时,会发现提交的job不在job列表中,即无法通过jobs查看。[root@pvcent107~]#(pingwww.ibm.com&)[root@pvcent107~]#ps-ef|grepwww.ibm.comroot162701014:13pts/400:00:00pingwww.ibm.comroot1627815362014:13pts/400:00:00grepwww.ibm.com[root@pvcent107~]#新提交进程的父ID(PPID)为1(init进程的PID),而不是当前终端的进程ID。因此,它不属于当前终端的子进程,所以不会受到当前终端的HUP信号的影响。2、disown使用场景:如果在命令前加上nohup或setsid,可以避免HUP信号的影响。但是如果我们不经任何处理就提交了命令,如何补救才能避免HUP信号的影响呢?解决方案:此时再添加nohup或setsid已经来不及了,只能通过jobscheduling和disown来解决问题。使用disown-hjobspec让作业忽略HUP信号。使用disown-ah让所有作业忽略HUP信号。使用disown-rh使正在运行的作业忽略HUP信号。使用disown时,目标job将从job列表中移除,我们将无法再使用jobs查看,但仍可以使用ps-ef查找。disown示例1(如果你在提交命令的时候已经使用“&”将命令放入后台,可以直接使用“disown”)[root@pvcent107build]#cp-rtestLargeFilelargeFile&[1]4825[root@pvcent107build]#jobs[1]+运行cp-i-rtestLargeFilelargeFile&[root@pvcent107build]#disown-h%1[root@pvcent107build]#ps-ef|greplargeFileroot4825968109:46pts/400:00:00cp-i-rtestLargeFilelargeFileroot4853968009:46pts/400:00:00greplargeFile[root@pvcent107build]#logoutdisown放到后台,用CTRL-z和“bg”将其放入后台,然后使用“disown”)[root@pvcent107build]#cp-rtestLargeFilelargeFile2[1]+Stoppedcp-i-rtestLargeFilelargeFile2[root@pvcent107build]#bg%1[1]+cp-i-rtestLargeFilelargeFile2&[root@pvcent107build]#jobs[1]+运行cp-i-rtestLargeFilelargeFile2&[root@pvcent107build]#disown-h%1[root@pvcent107build]#ps-ef|greplargeFile2root57905577110:04pts/300:00:00cp-i-rtestLargeFilelargeFile2root58245577010:05pts/300:00:00greplargeFile2[root@pvcent107build]#3:screen使用场景:我们已经知道如何保护进程不受HUP信号影响,但是如果有大量这样的命令需要在稳定的后台运行,如何避免对每个命令都这样做呢?解决办法:这个时候最方便的方法就是screen。简单来说,screen提供了一个ANSI/VT100终端仿真器,使其能够在一个真实终端下运行多个全屏伪终端。screen的参数非常多,功能也很强大。使用screen-dmS(sessionName)在断开模式下建立会话(并指定其会话名称)。使用screen-list列出所有会话。使用screen-r(sessionName)重新连接到指定的会话。使用快捷键CTRL-ad暂时断开当前会话。screeninstance[root@pvcent107~]#screen-dmSUrumchi[root@pvcent107~]#screen-list有一个screenon:12842.Urumchi(Detached)1Socketin/tmp/screens/S-root.[root@pvcent107~]#screen-rUrumchi当我们使用“-r”连接到screen会话后,我们就可以在这个伪终端中为所欲为,再也不用担心HUP信号影响我们的进程了,我们不必在每个命令前添加“nohup”或“setsid”。不使用screen时新进程的进程树[root@pvcent107~]#pingwww.google.com&[1]9499[root@pvcent107~]#pstree-H9499init─┬─Xvnc├─acpid├─atd├─2*[sendmail]├─sshd─┬─sshd────bash────pstree│└─sshd────bash────屏幕不ping的时候,我们所在的bash是sshd的子进程。当连接打开后,HUP信号自然会影响到它下面的所有子进程(包括我们新建立的ping进程)。使用screen后新进程的进程树[root@pvcent107~]#screen-rUrumchi[root@pvcent107~]#pingwww.ibm.com&[1]9488[root@pvcent107~]#pstree-H9488init─┬─Xvnc├─acpid├─atd├─screen────bash──ping├─2*[sendmail]使用screen后就不一样了。此时bash是screen的子进程,screen是init(PID为1的子进程)。那么当ssh断开的时候,HUP信号自然不会影响到屏幕下的子进程了。
