
linux 和 unix 属于多任务的操作系统,也就是说一个系统在同一时间段内能运行多重任务(进程)。在这个新的博客系列,我将会列出相关的 linux 和 unix 作业(job)控制的命令,你可以通过这些命令在 bash 或 korn 还有 posix shell 下实现执行多重任务。
<a target="_blank"></a>
作业控制不只是能够停止/挂起(stop/suspend)正在执行的进程(命令),也可以继续/唤醒(continue/resume)执行你需要的每一个进程。这完全可以用你的操作系统和 bash/ksh 之类的 shell 或 posix shell 完成。
bash / korn shell,或者是 posix shell 提供给了作业控制的环境。
你的 shell 会留有一张当前作业的表单,称为作业表。当你键入命令时,shell 会给它分配一个 jobid(也称作 jobspec)。一个 jobid 或 jobspec只是很小的整数数值。
我要运行一个名为 xeyes 的命令,它会在屏幕上显示两个椭圆的眼睛,输入: $ xeyes &
输出样例:
fig.01: 在后台运行 xeyes 命令
我使用&符号让一个 job 在后台运行。shell 会打印一行信息类似如下:
[1] 6891
在这个例子中,有两个数字输出,分别表示:
6891 : 作业1的进程id。
我在多执行一些 job:
## 启动一个文本编辑器,x 的系统负载显示,和 sleep 命令 ##
gedit /tmp/hello.c &
xload &
sleep 100000 &
$ jobs
$ jobs -l
输出如下:
[1] 9379 running xeyes &
[2] 9380 running gedit /tmp/hello.c &
[3]- 9420 running xload &
[4]+ 9421 running sleep 100000 &
简要描述如下:
字段
值
描述
示例
1
[1]
jobid 或 job_spec - 工作号要与fg, bg, wait, kill和其他shell命令一起使用。你必须在工作号前缀添加一个百分号:(%)。
加号 (+) 标识着默认的或是现在的作业。
减号 (-) 标识着前一个作业。
%1
fg %1
kill %2
2
9379
进程 id - 系统自动为每个进程创建并分配地独有的身份标志号。
kill 9379
3
running
状态 - 关于作业的状态:
running - 该 作业正在运行,还没有被外部信号挂起。
stopped - 该作业已经被挂起。
n/a
4
xeyes &
command - 由shell给出的命令。
script &
firefox url&
你也可以用 ps 命名列出当前系统正在运行的进程:
$ ps
kill -s stop pid
animated gif 01: 挂起 ping 命令作业
## ping 命令的作业号的值为5 ##
fg %5
我也可以规定命令行开端符合字符串"ping"的作业[译注:不能出现不明确的字符串,例如如果后台有两个 vim 进程而你敲入 fg %vim 会报错。]:
## %string ##
fg %ping
64 bytes from www.cyberciti.biz (75.126.153.206): icmp_req=3 ttl=53 time=265 ms
64 bytes from www.cyberciti.biz (75.126.153.206): icmp_req=4 ttl=53 time=249 ms
64 bytes from www.cyberciti.biz (75.126.153.206): icmp_req=5 ttl=53 time=267 ms
^c
# yum -y update &>/root/patch.log &
然而,由于一些原因(例如,过载问题)我决定停止这个作业20分钟:
# kill -s stop %yum
[7]+ stopped yum -y update &>/root/patch.log &
用 bg 重启停止在后台的 yum 进程
# bg %7
或者:
# bg %yum
[7]+ yum -y update &>/root/patch.log &
# kill %7
或者
# kill 进程id
[7]+ terminated yum -y update &>/root/patch.log &
~/scripts/www/pdfwriter.py --profile=faq --type=clean --header=logo\
--footer-left "nixcraft is git ul++++ w+++ c++++ m+ e+++ d-" \
--footer-right "page [of] of [total]" &
$ ~/scripts/www/pdfwriter.py --profile=faq .... &
$ disown
$ exit
$ nohup ~/scripts/www/pdfwriter.py --profile=faq .... &
为了查找最近在后台执行的(异步)命令的进程id,可使用 bash shell 的特殊参数 $!
$ gedit foo.txt &
$ echo "最近在后台执行的job 的pid - $!"
最近在后台执行的job 的pid - 9421
wait 命令会等候给予的进程id 或 作业id指定的进程,然后报告它的终止状态。语法如下:
/path/to/large-job/command/foo &
wait $!
/path/to/next/job/that-is-dependents/on-foo-command/bar
这是我的一个工作脚本:
#!/bin/bash
# a shell script wrapper to create pdf files for our blog/faq section
########################################################################
# init() - must be run first
# purpose - create index file in $_tmp for all our wordpress databases
init(){
_php="/usr/bin/php"
_phpargs="-d apc.enabled=0"
_base="~/scripts"
_tmp="$_base/tmp"
_what="$1"
for i in $_what
do
[[ ! -d "$_tmp/$i" ]] && /bin/mkdir "$_tmp/$i"
$_php $_phpargs -f "$_base/php/rawsqlmaster${i}.php" > "$_tmp/$i/output.txt"
done
}
#####################################################
# without index file, we can out generate pdf files
init blog
###########################################################
# do not run the rest of the script until init() finished
## alright, create pdf files
~/scripts/www/pdfwriter.py --profile=blog --type=clean --header=logo\
--footer-right "page [of] of [total]"
命令
&
将作业置入后台
命令 &
%n
设置作业号为 n (数字)的作业
命令 %1
%word
引用命令行开端包含 word 的作业
命令 %yum
%?word
引用命令行包含 word 的作业
命令 %?ping
%%
%+
引用当前作业
kill %%
kill %+
%-
引用先前作业
bg %-
ctrl-z
kill -s stop jobid
挂起或停止作业
kill -s stop %ping
jobs
jobs -l
列出活动的作业
bg
将 作业置入后台
bg %1
bg %ping
fg
将作业置入前台
fg %2
fg %apt-get
运行下面的 type 命令找出给予命令是否属于内部或外部的。
type -a fg bg jobs disown
输出样式:
fg is a shell builtin
fg is /usr/bin/fg
bg is a shell builtin
bg is /usr/bin/bg
jobs is a shell builtin
jobs is /usr/bin/jobs
disown is a shell builtin
在几乎所有情况下,你都需要使用 shell 的内置命令。所有外部命令例如 /usr/bin/fg 或 /usr/bin/jobs 工作在一个不同的 shell 环境下,而不能用在父 shell 的环境下。
原文发布时间为:2014-03-13
本文来自云栖社区合作伙伴“linux中国”