在shell中,作业控制指选择性地停止(暂停)并在后来继续(恢复)执行某个进程的能力。通常,用户通过操作系统内核的终端驱动和bash共同提供的功能,在交互式的界面上进行作业控制。shell把每个管道和一个作业关联起来,维护着一个当前正在执行的作业表,这个表可以使用内建命令jobs列出,下面先介绍一下jobs命令的用法。
jobs [-lnprs] [ jobspec ... ]
jobs -x command [ args ... ]
jobs命令的第一种格式用于列出当前活动的作业,其各选项的含义如下。
“-l”:列出各作业的正常信息外,还列出各作业对应的进程号。
“-n”:只显示状态发生改变的作业。
“-p”:只列出各作业的进程组中主进程的进程号。
“-r”:只显示正在运行的作业。
“-s”:只显示已停止的作业。
“jobspec”:只列出与jobspec匹配的作业。在作业队列中,从1开始对各作业排序,最后一个进入作业队列的序号最大,并用加号标记,它前面的一个作业标记为减号,其余的作业则没有这种标记。格式为“%n”
,n表示作业序号,是一个数字,省略百分号也是可以的,另外“%+”
、“%%”
或“%”
表示序号最大的作业、“%-”
表示比最大序号小1的作业。格式还可以是“%?string”
,string为某个后台作业的命令的子字符串。
例子:
$ while true; do pwd > /dev/null; done &
[1] 26747
$ while true; do ls > /dev/null; done &
[2] 26748
$ while true; do uname > /dev/null; done &
[3] 2737
$ while true; do tree > /dev/null; done &
[4] 23948
$ jobs -l
[1] 26747 Running while true; do
pwd > /dev/null;
done &
[2] 26748 Running while true; do
ls --color=auto > /dev/null;
done &
[3]- 2737 Running while true; do
uname > /dev/null;
done &
[4]+ 23948 Running while true; do
tree > /dev/null;
done &
上面的例子中,使用符号“&”
执行后台命令,对于一个正在前台执行的作业,可以使用组合键“Ctrl+Z”
暂停这个作业并把它放到后台,状态为“Stopped”。前台、后台作业的切换、执行可使用内建命令fg、bg。
fg [jobspec ...]
bg [jobspec ...]
fg命令把某个后台作业切换到前台执行,这个后台作业的状态可能为“Running”或“Stopped”。bg命令使某个停止的后台作业即状态为“Stopped”的作业恢复运行,还是在后台执行,状态变为“Running”。
接着上面的例子,使用fg命令和“Ctrl+Z”
组合键:
$ fg
while true; do
tree > /dev/null;
done
^Z
[4]+ Stopped while true; do
tree > /dev/null;
done
$ jobs -l
[1] 26747 Running while true; do
pwd > /dev/null;
done &
[2] 26748 Running while true; do
ls --color=auto > /dev/null;
done &
[3]- 2737 Running while true; do
uname > /dev/null;
done &
[4]+ 23948 Stopped while true; do
tree > /dev/null;
done
使用bg命令:
$ bg
[4]+ while true; do
tree > /dev/null;
done &
$ jobs -l
[1] 26747 Running while true; do
pwd > /dev/null;
done &
[2] 26748 Running while true; do
ls --color=auto > /dev/null;
done &
[3]- 2737 Running while true; do
uname > /dev/null;
done &
[4]+ 23948 Running while true; do
tree > /dev/null;
done &
关于作业控制,还有几个内建命令可以使用,kill、wait、disown、suspend。
kill [-s sigspec | -n signum | -sigspec] [pid | jobspec] ...
kill -l [sigspec | exit_status]
wait [-n] [N ...]
disown [-ar] [-h] [jobspec ...]
suspend [-f]
使用kill命令发送SIGKILL信号(对应的数字为9)给作业队列中的第二个作业:
$ kill -9 %2
$ jobs -l
[1] 26747 Running while true; do
pwd > /dev/null;
done &
[2] 26748 Killed while true; do
ls --color=auto > /dev/null;
done
[3]- 2737 Running while true; do
uname > /dev/null;
done &
[4]+ 23948 Running while true; do
tree > /dev/null;
done &
wait命令用于等待子进程的结束。
disown命令用于从作业表中移除指定作业。
使用disown命令的选项“-a”清空作业表,即移除所有作业。
$ disown -a
suspend命令用于暂停当前shell的执行,直到收到信号SIGCONT。