当前位置: 首页 > 科技观察

linux中如何让一个进程在后台运行

时间:2023-03-16 16:25:56 科技观察

一、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),不是当前终端。将此示例与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已经来不及了,只能通过job调度和disown来解决这个问题,使用disown-hjobspec让一个job忽略HUP信号。使用disown-ah让所有作业忽略HUP信号。使用disown-rh使正在运行的作业忽略HUP信号。使用disown时,目标job将从job列表中移除,我们将无法再使用jobs查看,但仍可以使用ps-ef查找。disown示例1(如果你在提交命令的时候已经使用“&”在后台运行命令,可以直接使用“disown”)[root@pvcent107build]#cp-rtestLargeFilelargeFile&[1]4825[root@pvcent107build]#作业[1]+Runningcp-i-rtestLargeFilelargeFile&[root@pvcent107build]#disown-h%1[root@pvcent107build]#ps-ef|greplargeFileroot4825968109:46pts/400:00:00cp-i-rtestLargeFilelargeFilelargeroot4853968009:46pts/400:00File0File0[root@pvcent107build]#logoutdisown示例2(如果提交命令时不使用"&"将命令放入后台,可以使用CTRL-z和"bg"将其放入后台,然后使用“disown”)[root@pvcent107build]#cp-rtestLargeFilelargeFile2[1]+Stoppedcp-i-rtestLargeFilelargeFile2[root@pvcent107build]#bg%1[1]+cp-i-rtestLargeFilelargeFile2&[root@pvcent107build]#jobs[1]+Runningcp-i-rtestLargeFilelargeFile2&[root@pvcent107build]#disown-h%1[root@pvcent107build]#ps-ef|greplargeFile2root57905577110:04pts/300:00:00cp-i-rtestLargeFilelargeFile2root58245577010:05pts/300:00:00greplargeFile2[root@pvcent107]使用三:构建场景:我我们已经知道如何保护进程免受HUP信号的影响,但是如果有大量这样的命令需要在稳定的后台运行,如何避免对每个命令都这样做呢?解决办法:这时候最方便的方法就是screen。简单来说,screen提供了一个ANSI/VT100终端仿真器,使其能够在一个真实终端下运行多个全屏伪终端。screen的参数非常多,功能也很强大。使用screen-dmS(sessionName)在断开模式下建立会话(并指定其会话名称)。使用screen-list列出所有会话。使用screen-r(sessionName)重新连接到指定的会话。使用快捷键CTRL-ad暂时断开当前会话。screeninstance[root@pvcent107~]#screen-dmSUrumchi[root@pvcent107~]#screen-listThereisascreenon:12842.Urumchi(Detached)1Socketin/tmp/screens/S-root.[root@pvcent107~]#screen-rUrumchiwhen在我们使用“-r”连接到屏幕会话之后,我们就可以在这个伪终端中做任何我们想做的事情了。我们不再需要担心HUP信号影响我们的进程,我们也不需要添加“nohup”或“setsid”。不使用屏幕时新进程的进程树[root@pvcent107~]#pingwww.google.com&[1]9499[root@pvcent107~]#pstree-H9499init─┬─Xvnc├─acpid├─atd├─2*[sendmail]├─sshd─┬─sshd────bash────pstree│└─sshd────bash────ping在不使用screen的时候,我们所在的bash是一个子进程sshd。当ssh断开时,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信号自然不会影响到屏幕下的子进程了。