前言
当用户只有一个bash环境,而又想同时干多样事情,那么就可以用工作管理机制。值得注意的是,放进后台的工作不能够和用户有交互,例如vim是不可能在后台自动运行的。
用法
&指示符
#tar -zpcf /tmp/etc.tar.gz /etc &
[1] 8000 <=== [job number] PID
在命令后面添加 & 符号,命令就会在后台执行。另外,因为命令的输出并没有被重定向(如 stdout ,stderr),所以有输出的话还是会输出在屏幕,可以通过输出重定向解决(>&)。
通过job命令查看命令执行的情况:
jobs [-lrs]
-l 列出job number, 命令串外,还包括pid
-r 仅列出后台run的工作
-s 仅列出在后台stop的工作
#jobs -l
[2] 5467 已完成 tar -zpcf /tmp/etc.tar.gz /etc
发现,已经完成了,在次查看时完成信息不在列出。
“暂停”:[ctrl]+z
如正在用vim编辑,按下[ctrl]+z,那么将在后台以stop状态存在。
root@jammg:/etc# jobs -l
[1] 4747 停止 find / -name a
[2]- 6073 停止 vim a
[3]+ 6086 停止 vim b
上面的+代表最后放进后台的工作,-则代表倒数第二个。
fg、bg命令
fg、bg分别是将工作在前台、后台运行,用法:
#fg %jobnumber
#bg %jobnumber
fg
以上面为例:
root@jammg:/etc# fg %2 // 再按下ctrl + z
vim a
[2]+ 已停止 vim a
root@jammg:/etc# jobs -l
[1] 4747 停止 find / -name a
[2]+ 6073 停止 vim a
[3]- 6086 停止 vim b
此时2变成+了, 可以通过"fg -"命令执行-号的哪个工作。
bg
root@jammg:/etc# jobs;bg %3 ; jobs
[1] 已停止 find / -name a
[2]+ 已停止 vim a
[3]- 已停止 vim b
[3]- vim b &
[1]- 已停止 find / -name a
[2]+ 已停止 vim a
[3] 运行中 vim b &
发现,通过bg调度3工作后,由-变为“放进后台的时间”再向前一步了,效果和fg相反。
存在的问题
工作管理(job control) 存在的问题是,如果我远程登陆主机,并以工作管理机制后台运行,那么远程断开连接时,工作也将停止,所以这也就是工作管理所谓的“后台”,它指的是在此工作模式下避免ctrl+c中断工作,工作依然和终端机有关,和系统后台有很大区别。
其实像at,cron可以解决这个问题!
以下通过nohup命令可以解决这个问题,它可以让你脱机或注销了远程系统后,还能让工作继续进行。
nohup用法
#nohup [命令与参数] [&]
&意义和工作管理一致, 注意,nohup不支持bash内置命令,我们可以新建一个shell脚本,将要执行的命令写进去,然后用nohup命令执行shell脚本。
补充
kill命令
利用kill -signal %jobnumber也可直接传递signal给相应进程。
nohup工作原理
在这里会涉及进程,进程组,会话,控制终端,shell的概念。
那么,nohup比at命令不同于哪里呢?
当控制终端被关闭时,拥有该终端的回话会向所有属于该回话的进程发送SIGHUP、SIGTERM和SIGQUIT信号,所以即使at以“后台”方式运行,它依然会停止工作,因为它始终是属于这个会话;而nohup就是根据这个特性,在每个属于该会话的进程安插了忽略上述信号的代码,所以能做到终端关闭而进程继续运行。
当然了,此时进程再进行I/O是会发生错误的,可以通过ioctl函数获取控制终端。
另外,还有一种解决方法,那就是daemon(守护进程)。