【Bash百宝箱】shell作业控制(jobs、bg、fg)

朱兴学
2023-12-01

在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。

 类似资料: