10 个 Linux/Unix Bash 和 KSH Shell 作业控制示例

[ad_1]

[donotprint]

[/donotprint]

大号
inux 和 Unix 是多任务操作系统,即可以在同一时间段内运行多个任务(进程)的系统。 在这个新的博客系列中,我将列出可用于通过 Bash、Korn 或 POSIX shell 进行多任务处理的 Linux 和 Unix 作业控制命令。

什么是工作控制?

作业控制不过是停止/暂停进程(命令)执行并根据您的要求继续/恢复执行的能力。 这是使用您的操作系统和 shell 完成的,例如 bash/ksh 或 POSIX 外壳。

谁提供了控制工作的设施?

Bash / Korn shell 或 POSIX shell 提供了控制作业的工具。

向工作表问好

您的 shell 保留了一张当前作业表,称为作业表。 当您键入命令时,shell 会分配一个 jobID(也称为 JOB_SPEC)。 jobID 或 JOB_SPEC 只不过是小整数。

#1:创建你的第一个 Linux/Unix 作业

我将运行一个名为 xeyes 的命令,它会在屏幕上显示两只粘糊糊的眼睛,输入:
$ xeyes &

示例输出:

Fig.01: Running the xeyes command in the background

我在后台使用与号 (&) 开始了一项工作。 shell 打印出如下所示的一行:

[1] 6891

在本例中,输出两个数字如下

  • [1] :在后台启动的 xeyes 作业是作业号 1。
  • 6891:作业号 1 的进程 ID。

我将开始更多的工作:

## Start a text editor, system load average display for X, and sleep command ##
gedit /tmp/hello.c &
xload &
sleep 100000 &

#2:列出当前的工作

要查看当前 shell 中活动作业的状态,请键入:
$ 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] 工作ID 或者 作业规格 – 与 fg、bg、wait、kill 和其他 shell 命令一起使用的作业号。 您必须在作业编号前加上百分号 (%)。
加号 (+) 标识默认或当前作业。
减号 (-) 标识上一个作业。
%1
fg %1
杀死 %2
2 9379 进程号 – 在系统上创建每个进程时自动分配给每个进程的唯一标识号。 杀死9379
3 跑步 状态 – 工作状态:
跑步 – 作业当前正在运行并且没有被信号挂起。
停止 – 作业被暂停。
不适用
4 xeyes & 命令 – 给 shell 的命令。 脚本 &firefox 网址&

您还可以使用 ps 命令列出系统上运行的进程:
$ ps

#3:停止或暂停正在运行的作业

打 [Ctrl]-[Z] key 或使用 kill 命令如下:

kill -s stop PID

在此示例中,启动 ping 命令并使用 Ctrl-Z 键序列停止 ping 命令作业:

#4:在前台恢复暂停/停止的工作

让我们恢复或将停止的 ping 作业带到前台,并在 fg 命令的帮助下使其成为当前作业。 语法如下:

## Job id number 5 for ping command ##
fg %5

我还可以声明命令行以字符串“ping”开头的任何作业:

## %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

#5:在后台恢复暂停/停止的工作

在本例中,我将使用 yum 命令后台作业更新 Red Hat 或 CentOS Linux 生产服务器上所有已安装的软件包:
# yum -y update &>/root/patch.log &

但是,由于某种原因(比如负载问题),我决定停止这项工作 20 分钟:
# kill -s stop %yum

示例输出:

[7]+  Stopped                 yum -y update &>/root/patch.log &

使用 bg 重新启动已停止的后台 yum 进程

现在,我要恢复停止 yum -y update &>/root/patch.log & 作业,输入:
# bg %7

或者
# bg %yum

示例输出:

[7]+ yum -y update &>/root/patch.log &

#6:杀死一个工作/进程

要停止/杀死 yum 命令进程,请输入以下 jobID 为 7 的 kill 命令:
# kill %7

或者
# kill pid

示例输出:

[7]+  Terminated              yum -y update &>/root/patch.log &

在 Linux/FreeBSD/OS X Unix 上,您可以使用 killall 命令按名称而不是 PID 或 jobID 来杀死进程。

#7 为什么当我注销时 shell 会杀死我所有的后台作业?

在此示例中,我将启动 pdfwriter.py 作业以批量生成此站点的 pdf 文件:

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

一旦我从 shell 注销,pdfwriter.py 作业就会被我的 shell 杀死。 为了克服这个问题,使用 disown shell 构建命令告诉 shell 不要发送 HUP 信号,输入:
$ ~/scripts/www/pdfwriter.py --profile=faq .... &
$ disown
$ exit

#8 使用名为 nohup 的外部命令防止作业在注销时被终止

您还可以在退出 shell 提示后使用 nohup 命令执行作业:
$ nohup ~/scripts/www/pdfwriter.py --profile=faq .... &
$ exit

#9:查找上一个作业的 PID

要查找最近执行的后台(异步)命令的进程 ID,请使用 bash 外壳特殊参数 $!
$ gedit foo.txt &
$ echo "PID of most recently executed background job - $!"

示例输出:

PID of most recently executed background job - 9421

#10:等待工作完成

wait 命令等待给定的进程 ID 或 jobID(作业规范),并报告其终止状态。 语法如下:

/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
###########################################################
wait $!
 
## Alright, create pdf files 
~/scripts/www/pdfwriter.py --profile=blog --type=clean --header=logo
--footer-left "nixCraft is GIT UL++++ W+++ C++++ M+ e+++ d-" 
--footer-right "Page [of] of [total]"

Linux和Unix作业控制命令列表汇总

命令 描述 例子)
& 将作业置于后台 命令 &
%n 使用给定的 n(数字)设置作业 命令 %1
%单词 引用命令行以 Word 开头的作业 命令 %yum
%?单词 引用命令行中包含 Word 的任何作业 命令 %?ping
%%
%+
参考当前工作 杀死%%
杀死%+
%- 参考之前的工作 bg %-
CTRL-Z
kill -s stop jobID
暂停或停止作业 kill -s 停止 %ping
工作
工作-l
列出活动作业 工作-l
bg 将工作置于后台 背景 %1
bg %平
fg 把工作放在前台 %2
fg %apt-get

关于 shell 内置和外部命令的说明

运行以下 键入命令 找出给定的命令是内部的还是外部的:

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 的环境。

结论

我希望你喜欢这个博客文章系列(rss feed),我建议你阅读以下内容以获取更多信息:

  • 有关 Linux/Unix 进程管理的 disown 命令示例、jobs 命令示例、bg 命令示例和 fg 命令示例,请参阅我们的常见问题解答部分。
  • 手册页 – kill(1)
  • Korn shell (ksh93) 文档.
  • GNU bash 外壳文档.

我计划在本系列中添加更深入的教程。 如果您需要在下面的评论部分查看特定主题,请告诉我。

[ad_2]

Related Posts