10个 Linux/Unix下 Bash 和 KSH shell 的作业控制实例
Linux 和 Unix 属于多任务的操作系统,也就是说一个系统在同一时间段内能运行多重任务(进程)。在这个新的博客系列,我将会列出相关的 Linux 和 Unix 作业(job)控制的命令,你可以通过这些命令在 Bash 或 Korn 还有 POSIX shell 下实现执行多重任务。
什么是作业控制?
作业控制不只是能够停止/挂起(stop/suspend)正在执行的进程(命令),也可以继续/唤醒(continue/resume)执行你需要的每一个进程。这完全可以用你的操作系统和 bash/ksh 之类的 shell 或 POSIX shell 完成。
谁给作业控制的提供了环境?
Bash / Korn shell,或者是 POSIX shell 提供给了作业控制的环境。
跟作业表打个招呼吧
你的 shell 会留有一张当前作业的表单,称为作业表。当你键入命令时,shell 会给它分配一个 jobID(也称作 JOBSPEC)。一个 jobID 或 JOBSPEC只是很小的整数数值。
#1: 创建你的首个 Linux/Unix 作业
我要运行一个名为 xeyes 的命令,它会在屏幕上显示两个椭圆的眼睛,输入: $ xeyes &
输出样例:
Fig.01: 在后台运行 xeyes 命令
我使用&符号让一个 job 在后台运行。shell 会打印一行信息类似如下:
- [1] 6891
在这个例子中,有两个数字输出,分别表示:
- 1 : 在后台执行的 xeyes 任务的作业号为 1。
- 6891 : 作业1的进程ID。
我在多执行一些 job:
- ## 启动一个文本编辑器,X 的系统负载显示,和 sleep 命令 ##
- 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] |
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
#3: 停止或挂起正在运行的作业
按下[Ctrl]-[Z]键或使用kill 命令,如下所示:
- kill -s stop PID
举个例子,启动ping 命令,然后用 Ctrl-Z 键来停止 ping 命令作业:
Animated gif 01: 挂起 ping 命令作业
#4: 在前台恢复 挂起的/停止的作业
让我们恢复处于停止状态下的作业,让它回到前台继续运行,要将其变成当前作业,必须借助fg 命令。具体语法如下:
- ## 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
#5: 在后台恢复 挂起/停止状态的作业
在这个例子中,我使用yum 命令更新所有安装在 Redhat 或 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 命令进程,输入如下kill 命令及其作业号 7:
- # kill %7
或者
- # kill 进程ID
输出样例:
- [7]+ Terminated yum -y update &>/root/patch.log &
在 Linux/FreeBSD/OS X Unix 下你也可以使用 killall 命令通过名字杀死进程或是 jobID 而不是通过 PID
#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 杀死。为了克服这个问题需要使用shell的内置命令 disown 来告诉 shell 不要发送 HUP 信号,键入:
- $ ~/scripts/www/pdfwriter.py --profile=faq .... &
- $ disown
- $ exit
#8 使用一个名为 nohup 的外部命令阻止在登出时杀死作业
你也可以使用nohup 命令在你退出 shell 后执行作业:
- $ nohup ~/scripts/www/pdfwriter.py --profile=faq .... &
- $ exit
#9: 查找最后的作业的 PID
为了查找最近在后台执行的(异步)命令的进程ID,可使用 bash shell 的特殊参数 $!
- $ gedit foo.txt &
- $ echo "最近在后台执行的job 的PID - $!"
输出样例:
- 最近在后台执行的job 的PID - 9421
#10: 等候作业完成
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
- ###########################################################
- 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 | 引用命令行开端包含 Word 的作业 | 命令 %yum |
%?Word | 引用命令行包含 Word 的作业 | 命令 %?ping |
%% %+ |
引用当前作业 |
kill %% kill %+ |
%- | 引用先前作业 | bg %- |
CTRL-Z kill -s stop jobID |
挂起或停止作业 | kill -s stop %ping |
jobs jobs -l |
列出活动的作业 | jobs -l |
bg | 将 作业置入后台 |
bg %1 bg %ping |
fg | 将作业置入前台 |
fg %2 fg %apt-get |
关于 shell 内置命令和外部命令的小注
运行下面的 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 的环境下。
总结
我希望你能喜欢这篇博文系列(rss 订阅),我建议你阅读下面的更多信息:
- 在我们的 faq 章节查阅有关进程管理的文章disoen 命令示例,jobs 命令示例,bg 命令示例,和fg 命令示例。
- Man pages bash(1), ksh(1), ps(1), kill(1)
- Korn shell (ksh93) 文档.
- NU bash shell 文档.
10个 Linux/Unix下 Bash 和 KSH shell 的作业控制实例相关推荐
- 修改linux下全局数据库名,linux/unix下修改oracle数据库实例名的方法
linux/unix下修改oracle数据库实例名的方法 2018年12月10日 | 萬仟网IT编程 | 我要评论 linux/unix下修改oracle实例名的方法 1.检查原来的数据库实例名 $ ...
- linux 下 任务管理器,Linux/Unix下的任务管理器-top命令
Windows下的任务管理器虽然不好用(个人更喜欢Process Explorer些),但也算方便,可以方便的查看进程,CPU,内存...也可以很容易的结束进程 没有图形化界面下的Linux,也有命令 ...
- linux清理oracle磁盘空间,Linux / Unix 下文件删除、句柄 与空间释放问题
Linux / Unix 下文件删除.句柄 与空间释放问题 临时表空间,并切换了数据库设置:[oracle@corde tdb]$ ls -sort total 35101212 51264 -rw- ...
- Linux/Unix下的任务管理器-top命令
Linux/Unix下的任务管理器-top命令 Posted on 2012-07-11 09:14 fengyv 阅读(15453) 评论(1) 编辑 收藏 Windows下的任务管理器虽然不好用( ...
- Linux/Unix下tar命令详解
tar命令是Linux/Unix系统下的打包压缩工具,可以将多个文件合并为一个文件,打包后的文件后缀为".tar". 这里首先需要明确两个概念:打包和压缩.打包是指将一大堆文件或目 ...
- linux文件字节函数,各位大侠:linux/unix下有什么双字节的字符类型及其一整套处理函数? 高分送出,请帮帮小弟!!!!!!...
linux/unix下小弟需要操作双字节,相对单字节char 有什么双字节的字符类型及其一整套处理函数,如strstr(),strcpy(),strchr等功能相同的双字节操作函数,它用到什么头文件? ...
- linux/unix下telnet提示Escape character is ‘^]‘的意义
在linux/unix下使用telnet hostname port连接上主机后会提示Escape character is '^]' 这个提示的意思是按Ctrl + ] 会呼出telnet的命令行, ...
- Linux安装Flash脚本,Linux(CentOS)下的Shockwave Flash shell一键更新脚本
原创内容,转载请注明出处: https://www.myzhenai.com.cn/post/2318.html https://www.myzhenai.com/thread-17933-1-1.h ...
- 10 款 Linux 环境下的开源替代工具
在 Linux 操作系统下,我们经常使用 cat 命令去连接多个文件并打印到标准输出,合成几个文件为一个目标文件,追加几个文件到目标文件中. 最近我在 GitHub 上发现了一个具有相似作用的命令叫做 ...
最新文章
- Apriltag可用图片:TAG16H5
- Mac使用crontab来实现定时任务
- map集合——阅读理解(洛谷 P3879)
- Springboot 使用wangEditor3.0上传图片
- Mac下安装第三方模块报错:‘sqlfront.h‘ file not found的解决办法
- C#实现在图片上斜着写字
- Intellij IDEA中拉svn分支
- react代码编辑器 react-ace
- 安卓使用教程:(八门神器)破解游戏内购方法及原理
- c语言中阶乘相加怎么表示_c语言求阶乘累加和
- 基于cocos2d-lua的shader入门玩转
- java close 方法_Java PushbackReader close()方法与示例
- 前端框架 — Bootstrap
- 高通烧录报ufs需要重新provision
- [TJOI2015]弦论
- 在vue中使用element-ui二次封装面包屑导条
- python Deformation Transfer for Triangle Meshes
- 解除Windows 10休眠时自动唤醒设置
- 【打印机】斑马打印机指令简介
- 工作流引擎-协作模式-最后一个人发送选择到达节点与接受人的场景设计与实现...