天天看点

10个 Linux/Unix下 Bash 和 KSH shell 的作业控制实例

10个 Linux/Unix下 Bash 和 KSH shell 的作业控制实例

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 &amp;

输出样例:

10个 Linux/Unix下 Bash 和 KSH shell 的作业控制实例

fig.01: 在后台运行 xeyes 命令

我使用&amp;符号让一个 job 在后台运行。shell 会打印一行信息类似如下:

[1] 6891

在这个例子中,有两个数字输出,分别表示:

6891 : 作业1的进程id。

我在多执行一些 job:

## 启动一个文本编辑器,x 的系统负载显示,和 sleep 命令 ##

gedit /tmp/hello.c &amp;

xload &amp;

sleep 100000 &amp;

$ jobs

$ jobs -l

输出如下:

[1] 9379 running xeyes &amp;

[2] 9380 running gedit /tmp/hello.c &amp;

[3]- 9420 running xload &amp;

[4]+ 9421 running sleep 100000 &amp;

简要描述如下:

字段

描述

示例

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 &amp;

command - 由shell给出的命令。

script &amp;

firefox url&amp;

你也可以用 ps 命名列出当前系统正在运行的进程:

$ ps

kill -s stop pid

10个 Linux/Unix下 Bash 和 KSH shell 的作业控制实例

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 &amp;&gt;/root/patch.log &amp;

然而,由于一些原因(例如,过载问题)我决定停止这个作业20分钟:

# kill -s stop %yum

[7]+ stopped yum -y update &amp;&gt;/root/patch.log &amp;

用 bg 重启停止在后台的 yum 进程

# bg %7

或者:

# bg %yum

[7]+ yum -y update &amp;&gt;/root/patch.log &amp;

# kill %7

或者

# kill 进程id

[7]+ terminated yum -y update &amp;&gt;/root/patch.log &amp;

~/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]" &amp;

$ ~/scripts/www/pdfwriter.py --profile=faq .... &amp;

$ disown

$ exit

$ nohup ~/scripts/www/pdfwriter.py --profile=faq .... &amp;

为了查找最近在后台执行的(异步)命令的进程id,可使用 bash shell 的特殊参数 $!

$ gedit foo.txt &amp;

$ echo "最近在后台执行的job 的pid - $!"

最近在后台执行的job 的pid - 9421

wait 命令会等候给予的进程id 或 作业id指定的进程,然后报告它的终止状态。语法如下:

/path/to/large-job/command/foo &amp;

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" ]] &amp;&amp; /bin/mkdir "$_tmp/$i"

$_php $_phpargs -f "$_base/php/rawsqlmaster${i}.php" &gt; "$_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]"

命令

&amp;

将作业置入后台

命令 &amp;

%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中国”