分类 系统运维 下的文章

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]jobIDJOB\_SPEC - 工作号要与fg, bg, wait, kill和其他shell命令一起使用。你必须在工作号前缀添加一个百分号:(**%**)。加号 (+) 标识着默认的或是现在的作业。减号 (-) 标识着前一个作业。%1`fg %1`kill %2
29379进程 ID - 系统自动为每个进程创建并分配地独有的身份标志号。kill 9379
3Running状态 - 关于作业的状态:**Running** - 该 作业正在运行,还没有被外部信号挂起。**Stopped** - 该作业已经被挂起。N/A
4xeyes &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 %1bg %ping
**fg**将作业置入前台fg %2fg %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 订阅),我建议你阅读下面的更多信息:

我会计划在这个系列添加更多深入的教程。若果你需要看到具体的主题,请在下方评论让我知道。


via: http://www.cyberciti.biz/howto/unix-linux-job-control-command-examples-for-bash-ksh-shell/

译者:Luoxcat 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

如果你已经习惯了在Linux系统上工作,那你一定会发现在Linux世界中存在着大量的文本文件。配置文件和日志文件通常都采用文本格式。这些文件通常都有很长的内容,不能在一屏内全部显示。所以在处理这种文件时,我们需要分页显示。这时我们可以用上more命令。

more是干嘛的

more是一个用来分页显示大文本文件的命令,它默认是内置在各个Linux发行版中的。

怎么用more

使用more命令,只需要键入:

$ more file_name

比如,我们想检查/var/log目录下的日志文件syslog,只需要键入:

$ more /var/log/syslog

more命令

然后我们可以看到在屏幕左下角有个提示,告诉我们当前的显示比例为0%。看上去这个文件相当大,所以第一页是全部页数的0%。使用空格键可以往下翻页,然后就可以看到提示的百分比会增加。

Scroll page

限制每页显示的行数

在执行more命令的时候,它会占用你终端窗口的全部空间用于显示。但是你可以通过参数-数字来限制每页显示的行数。

例如,你希望每页限制显示12行,可以通过下面的命令:

$ more -12 /var/log/syslog

限制每页显示12行

现在,你会看到每页只显示12行,在按下空格键后,就会翻页显示后面的12行。

Display user message

我们知道,more命令会在显示区域的左下角提示当前内容所占的百分比。对于第一次使用more命令的人来说,他或她可能会想知道怎么才能往下翻页。为了避免这种情况,我们可以在执行时增加-d参数,这样就会额外显示一行用户信息“[按空格键继续,‘q‘推出.]”

More with -d option

如果用户按了‘空格‘或’q‘之外的按键,more会显示一行帮助信息“ [按‘h’键查看提示。]”

More displaying help message

如果按下h键,会显示一个帮助信息:

Display help

一个有意思的指令是b按钮,b按钮允许你退回到前面的页面。换句话说,b按钮可以允许向前翻页

你可以通过左上角的...前1页信息来确认当前显示的是前面的页面。

在more中往前翻页

禁止滚动

通过参数-c,more命令不会滚动页面,而是直接清除之前的内容,替换为下一页的内容。 With -c option, more will not scroll the page. It will clear the previous page and put the next page or lines there.

$ more -10 -c lynis.log

Suppress scroll

如果按下空格键,下一页会仍然有相同的大小。

Suppress scroll

忽略多余的空白行

使用参数-s来忽略多余的空白行,下面是个例子:

多个空白行的文件

当我们增加参数-s后:

$ more -s doc_30.txt

忽略了多余空白行

查找字符串

如果你的日志文件非常大,那么在其中查找你想要的字符串并不是那么容易。more命令的查找功能可以帮你,通过参数+/string可以用来搜索字符串,找到的关键字会显示在第一行。比如我们要在/var/logs/syslog文件中搜索“dhclient”,那more命令的格式:

$ more +/dhclient /var/log/syslog

查找字符串

然后,如果要在文件中继续搜索下一个,只需要按下/按钮,后面跟有关键字dhclient。

从指定行开始显示

你也可以通过参数+数字来指定开始显示的行,例如,我们有一个15行的文件:

多行文件

然后我们想从第5行开始显示这个文件的内容,命令看起来会是这个样子:

$ more +5 doc_30.txt

从指定行开始显示

可以显示二进制文件吗?

答案是不行. more命令会提示这样的信息,例如:

显示二进制文件

结论

more是一个用来查看文本文件的基础工具,它不能用来显示二进制文件。通常,我们可以通过命令man more或者more --help来获取更多关于more怎么使用的信息。


via: http://linoxide.com/linux-command/linux-more-command/

译者:zpl1025 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出