Linux保持命令在后台运⾏的⼏种⽅法及原理
记录⼀下Linux下使命令不受终端断开的影响,保持在后台运⾏的⼏个⽅法及其原理。当⽤户注销logout或者⽹络中断时,终端会受
HUP(hangup)信号从⽽关闭其所有⼦进程。
## 两种中断信号:
1)sigint:signal interrupt,ctrl+c会发送此信号,主动关闭程序
2)sighup: signal hang up,关闭终端,⽹络断线,关闭屏幕会发送此挂断信号。
解决⽅法⼤体有两种:要么让进程忽略HUP信号,要么让进程运⾏在新的会话⾥从⽽成为不属于此终端下的⼦进程。下⾯分别介绍⼏种⽅式,如果亲⾃动⼿验证⼀番会更有收获。
1、nohup命令可以让要执⾏的命令忽略HUP信号,再加上&可以保证命令⼀直在后台运⾏。
nohup ./test.sh > out.log 2>err.log &
后台不中断执⾏./test.sh,stdout输出给out.log,stderr输出给err.log
例:nohup commandXXX > test.log 2>&1 &
命令解析:含义是把stderr也重定向给stdin
nohup可以让commandXXX这个命令忽略HUP信号;
第⼀个>代表将命令的标准输出重定向到指定的地⽅,这⾥是test.log
2>&1代表重定向标准错误重定向到标准输出,这⾥标准输出已经被重定向到test.log,所以标准错误也会输出到test.log。这⾥引申⼀下:
Linux中的标准输⼊即STDIN , 在/dev/stdin ,⼀般指键盘输⼊, shell⾥代号是0;
Linux中的标准输出STDOUT, 在/dev/stdout,⼀般指终端(terminal), 就是显⽰器, shell⾥代号是1;
Linux中的标准错误STDERR,在/dev/stderr也是指终端(terminal),不同的是,错误信息送到这⾥ shell⾥代号是2
最后⼀个&表⽰让命令在后台运⾏
关闭终端后可以通过ps -ef|grep commandXXX命令查到后台进程。
0 – stdin (standard input),
1 – stdout (standard output),显然 nohup command > out.log 等价于 nohup command 1> out.log,是缺省⾏为。
2 – stderr (standard error)
2、setsid命令可以让进⾏运⾏在新的会话下,即不属于当前终端的⼦进程。那么即使当前终端发出了HUP信号,也不会影响该进程例:setsid commandXXX
其实通过观察进程中的⽗进程号(PPID)发现⼀些端倪,使⽤setsid后进⾏的PPID为1(即为init进程ID),并⾮当前终端的进程ID。
3(本地单元测试通过)将⼀个或多个命令⽤()括起来在shell中运⾏,所提交的作业并不在作业列表中,即⽆法通过jobs查看到。新提交的进程的PPID为1。
例:(commandXXX)
4、若未加上述任何处理就执⾏了命令,如何补救才能让其不受HUP信息的影响呢?
答案是作业调度。对于某个已执⾏的命令,经过以下⼏个步骤可以让其忽略HUP信号:
先使⽤ctrl+z命令将正在执⾏的命令变为job作业,;
使⽤jobs可以查看到具体的作业号(jobid);
再⽤bg %jobid命令让其在后台运⾏;
最后使⽤disown -h %jobid 即可使该作业忽略HUP信号
4.1 ctrl + z
将⼀个正在前台执⾏的作业进程放到后台,并且暂停,⽤术语讲就是挂起,执⾏后如下:
[1]+ Stopped ./test.sh
4.2 jobs
查看当前有多少在后台运⾏的命令,[jobnumber] 就是作业号。
jobs
[1]+ Stopped ./test.sh
[2]+ Running ./test2.sh &
4.3 bg
将后台中暂停(挂起)的作业进程继续运⾏,例如把1号作业(./test.sh) 放到后台运⾏,注意看已经带了&
bg 1
[1]+ ./test.sh  &
4.4 fg
将后台中的作业进程调⾄前台继续运⾏,例如把2号作业(./test2.sh &)调⾄前台运⾏
fg 2
./test2.sh
5、有⼤量这种需要稳定的在后台运⾏的命令时,如何避免对每条命令都做上述的重复操作呢?
5.1 介绍
答案是screen。screen提供了ANSI/VT100的终端模拟器,能够在⼀个真实终端下运⾏多个全屏的伪终端。screen具有很多参数,功能强⼤,在此仅简要分析⼀下为什么使⽤screen可以避免HUP信号的影响:
我们可以粗略地认为screen是⼀个虚拟终端软件,直接在linux系统⾥⾯启动了另外⼀个后台程序接管(维持)了你的终端会话,当你直接连接的终端ssh断开时他仍然让程序认为你的ssh持续链接着,这样也就不会出现进程接收到中断信号⽽退出。
⽤screen -dnS session new 建⽴⼀个处于断开模式下的会话(并指定其会话名);
⽤screen -list 列出所有会话;
⽤screen -r session name 重新连接指定会话;
⽤ctrl -a D暂时断开当前会话;
5.2 安装
yum -y install screen
5.3 使⽤
1)新建会话
screen -S yourname -> 新建⼀个叫yourname的session
linux终端下载软件2)列出当前所有的session
screen -ls
3)恢复会话(回到yourname这个session)
screen -r yourname
4) detach某个session
screen -d yourname -> 远程detach某个session
screen -d -r yourname -> 结束当前session并回到yourname这个session
5)删除会话
screen -S pid-X quit
当我们⽤-r连接到screen会话时,就进⼊了⼀个伪终端,不会再受到HUP信号的影响了。
6、其他命令:
pstree -H pid 查看进程号对应的进程命令的树形结构
fg %jobid 将某个挂起的进程放回前台
bg %jobid 将某个挂起的进程调到后台继续运⾏,这⼀点在调试代码时尤其有⽤,因为将代码编辑器挂起到后台再重新返回时,光标定位仍停留到上次挂起时的位置,避免了重新地凝望的⿇烦。
ctrl +c 停⽌当前命令
jobs -l 列出所有任务的pid,jobs的状态可以是running/stopped/terminated,但若任务终⽌了(kill),shell会从当前列表中删除任务的进程标识。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。