Linux 后台任务笔记
学习整理一下关于后台任务相关的内容,进一步的分析必须从Linux中的进程,信号等机制出发,但是我对此没啥兴趣,这里只是从实用的角度进行学习,浅尝辄止。
通常在shell中执行的任务都是前台任务,即任务会占用前台,在任务结束之前无法进行下一个任务。在命令结尾使用&
可以将命令使用后台进程执行,例如
1 | ./test.sh & |
其中的测试脚本在不断写入日志,每隔4秒写入一次 1
2
3
4
5
6
7
8
logfile="time_log.txt"
while true; do
echo "$(date)" >> "$logfile"
sleep 4
done
使用jobs
命令可以查看当前的后台任务,每一个后台任务都有独立的序号(注意不是pid),例如
1
[1]+ Running ./test.sh &
如果返回值为空,代表没有后台任务。后台任务的状态可能是Running(正在运行),也可能是Stopped(挂起,暂停),Terminated(终止),终止的任务稍后就会从jobs
的输出中消失。
需要注意的是,后台任务仍然会向当前终端的输出流写入信息!这可能会混淆其他命令的输出,对于后台任务,最好还是将输出重定向比较稳妥
1
./test.sh > output.log 2>&1 &
如果当前的前台任务太长或者卡死了,我们可以使用ctrl+c
强行结束前台任务,也可以使用ctrl+z
将前台任务挂起,此时任务会转为后台任务,并且设置为暂停状态,此时jobs
输出形如
1
[1]+ Stopped ./test.sh
使用fg %1
命令可以将指定的后台任务(正在执行或挂起的)转到前台执行。
使用bg %1
命令则可以将指定的后台挂起任务在后台执行,这些命令的百分号很重要)
1
2
3bg %1
fg %1
如果缺省编号,默认操作对象是标记为+
的最近任务,此外还有标记为-
的任务,含义是如果+
标记的任务结束,-
标记的任务就会变成+
标记。
使用kill
命令可以终止后台任务,例如
kill %jobnumber
或 kill PID
。
需要注意的是,在一个会话中,无论是前台任务还是后台任务都是从属于当前会话的,如果退出当前的登陆,后台任务也会被终止, 有两种方法来解决这种问题:
- 使用
nohup
命令; - 使用
setsid
命令。
第一种是基于nohup
的方法,可以使用nohup
搭配
&
来解决会话退出导致后台任务终止的问题,此时对应的进程不会因为退出会话而被终止,例如
1
nohup ./test.sh &
nohup
命令默认会将输出重定向到当前位置下的nohup.out
文件(如果当前位置无权限则会回到家目录下创建nohup.out
文件),在事后可以使用nohup.out
文件来查看这个后台任务的输出。
可以指定全部输出重定向到指定文件,例如 1
nohup ./test.sh > out.log 2>&1 &
nohup
命令有提示信息,需要回车确认一下。
如果对一个已经正在运行的后台任务忘记使用nohup
执行了,还可以使用disown
命令进行补救,例如
1
2./test.sh &
disown -h %1
第二种是基于setsid
的方法,它的做法在原理上更加彻底,此时的进程和当前会话不再是从属关系,因此当前会话的终止不会影响该进程,例如
1
setsid ./test.sh &
使用小括号似乎有一样的效果 1
(./test.sh &)