Linux中国 | Linux.cn - 我们的Linux中文社区

 找回密码
 加入

QQ登录

QQ登录

搜索

学习 Linux,101: 创建、监控和终止进程——关注正在运行的进程

热度 7已有 1490 次阅读2010-3-10 14:34 |个人分类:学习 Linux,101|关键词:linux 进程 学习

简介:了解 Linux® 上的进程管理:如何在前台和后台之间切换进程,找出正在运行的程序,终止进程,以及在外出时让进程继续运行。本文提供的材料可以帮助您准备 Linux 系统管理员认证 LPI 101 考试,也可以作为一般的兴趣读物。

概述

  本文深入介绍基础的 Linux 进程管理技术。您将学习如何:

  • 管理前台和后台作业
  • 启动在注销之后仍将运行的进程
  • 监控进程
  • 根据需要选择和排列进程的显示方式
  • 向进程发送信号

  本文帮助您准备 Linux Professional Institute's Junior Level Administration (LPIC-1) 考试的 103 主题下的 103.5 考核目标。该考核目标的权值为 4。

先决条件

  为了从本文获得最大的收益,您应该具备基础的 Linux 知识,并且具有一个能够正常运行的 Linux 系统,您将在 Linux 系统上练习本文讨论的命令。不同版本的程序输出的结果的格式可能不同,因此您的结果可能与本文图片和清单所示的结果有所不同。本文的例子显示的结果来自于 Ubuntu 9.10 (Karmic Koala) 发行版。

 


 

管理前台和后台作业

  您只要停下来仔细思考一下就会发现,除了本系列早期文章讨论的终端程序之外,您的电脑还运行着许多其他程序。事实上,如果您使用图形化桌面,您可能一次打开了多个终端窗口,或者打开了文件浏览器、Internet 浏览器、游戏、电子表格或其他应用程序。我们以前介绍的例子已经演示了在一个终端窗口中输入的命令。您要等待该命令运行完毕之后才能运行其他命令。在本文中,您将了解如何通过终端窗口一次运行多个命令。

  当您在终端窗口运行命令时,您是在前台 运行它。大部这些命令的运行都很快,但现在假设您运行的是图形化桌面,并且想在桌面上显示一个数字时钟。尽管大部分图形化桌面都有一个时钟,我们仍然以此作为例子。

  如果您安装了 X Window System,您也许会拥有一些实用程序,比如 xclock 或 xeyes。如果您还没有安装这些实用程序,您可以在名为 xorg-x11-apps 或 x11-apps 的包中找到它们。这两个包中的实用程序都可以在本例中使用,但我们选择使用 xclock。根据实用程序的手册页,您可以通过以下命令在图形化桌面上启动数字时钟:

 

xclock -d -update 1

 

  -update 1 部分请求每秒钟更新一次;如果取消该选项,时钟将每分钟更新一次。让我们在终端窗口中运行该命令。您将看到一个类似于图 1 的时钟,您的终端窗口类似于清单 1。如果您没有 xclock 或 X Window System,稍后您将看到如何在终端窗口中创建一个简易的数字时钟。现在,您先根据本文的步骤学习,并以该时钟作为例子进行练习。

  注意:在撰写本文时,有一个 bug 在启用桌面效果时会影响 xclock。最明显的影响是标题栏不变化,即使操作它时也是这样。如果您的 xclock 例子与本文的不同,您可能要关闭桌面效果一段时间。

图 1. 带有 xclock 字样的数字时钟

清单 1. 启动 xclock

 

ian@attic4:~$ xclock -d -update 1

 

  不幸的是,您的终端窗口不再出现命令提示符,因此您要恢复它。幸好 Bash shell 有一个暂停 键 Ctrl-z。按下该组合键将恢复终端提示符,如清单 2 所示。

清单 2. 使用组合键 Ctrl-z 暂停 xclock

 

ian@attic4:~$ xclock -d -update 1  
^Z
[1]+  Stopped                 xclock -d -update 1

 

  xclock 数字时钟仍然出现在桌面上,但它已经停止运行。事实上,如果您拖动另一个窗口让它与时钟的一部分重叠,时钟被重叠的部分仍然会保持不变。注意,终端输出消息显示 “[1]+  Stopped”。该消息中的 1 表是作业编号。您可以通过输入 fg %1 重新启动时钟。您还可以通过输入 fg %xclock 或 fg %?clo 使用命令名或命令名的一部分。最后,您仅需要输入不带任何参数的 fg 就可以重新启动最近停止的作业,如本例中的 job 1。使用命令 fg 重启任务还会将其带回到前台,因此不再出现 shell 提示符。您需要做的就是将作业放回到后台;bg 命令的作业指示与 fg 命令相同,它的作用就是将作业放回到后台。

  清单 3 显示如何将 xclock 作业带回到前台,并使用两种形式的 fg 命令暂停它。您可以再次暂停它并将它放到后台;此时,即使您在终端窗口运行其他程序,时钟仍会继续运行。

清单 3. 将 xclock 放在前台或后台

 

ian@attic4:~$ fg %1
xclock -d -update 1
^Z
[1]+  Stopped                 xclock -d -update 1
ian@attic4:~$ fg %?clo
xclock -d -update 1
^Z
[1]+  Stopped                 xclock -d -update 1
ian@attic4:~$ bg
[1]+ xclock -d -update 1 &

 

使用 “&”

  您可能已经注意到,当您将 xclock 放在后台时,该消息不再显示 “Stopped”,并且使用与符号 (&) 终止了它。事实上,您根本不需要暂停程序就可以将它放到后台;您仅需将一个与符号 (&) 添加到该命令的后面 shell 就会在后台启动该命令(或命令列表)。让我们通过该方法启动一个背景为白色的带指针时钟。您将看到类似于图 2 所示的时钟,其终端输出类似于清单 4。

图 2. 带有 xclock 字样的指针式时钟

清单 4. 使用 & 在后台启动指针式时钟

 

ian@attic4:~$ xclock -bg wheat -update 1&
[2] 4320

 

  注意,这次显示的消息与上一次略有不同。它显示一个作业编号和一个进程 ID(PID)。我们稍后将更详细地讨论 PID 和状态。目前我们使用 jobs 命令找出有多少个作业正在运行。添加 -l 选项来列出 PID,您将看到 job 2 的 PID 为 4320,如清单 5 所示。此外还要注意,job 2 的作业编号旁边有一个加号 (+),这表明它是现正在运行 的作业。如果 fg 命令不带有任何作业指示,该作业将出现在前台。

清单 5. 显示作业和进程信息

 

ian@attic4:~$ jobs -l
[1]-  3878 Running                 xclock -d -update 1 &
[2]+  4320 Running                 xclock -bg wheat -update 1 &

 

  在解决其他与后台作业相关的问题之前,我们先看看一个自制的简易数字时钟。我们使用 sleep 命令将显示推迟两秒,然后使用 date 命令打印当前的日期和时间。我们将这两个命令放在一个 while 循环中,该循环带有一个用于创建无限循环的 do/done 代码块。最后,我们将所有代码放在一对圆括号中构成一个命令列表,然后使用与号将整个列表放到后台。本系列后面的文章介绍如何使用循环和脚本构建更加复杂的命令。查看我们的 学习 Linux,101:LPIC-1 路线图 了解本系列,并获得每篇文章的链接。

清单 6. 简易的数字时钟

 

ian@attic4:~$ (while sleep 2; do date;done)&
[2] 4856
ian@attic4:~$ Tue Jan 19 09:23:30 EST 2010
Tue Jan 19 09:23:32 EST 2010
Tue Jan 19 09:23:34 EST 2010
fTue Jan 19 09:23:36 EST 2010
Tue Jan 19 09:23:38 EST 2010
gTue Jan 19 09:23:40 EST 2010

( while sleep 2; do
    date;
done )
Tue Jan 19 09:23:42 EST 2010
Tue Jan 19 09:23:44 EST 2010
Tue Jan 19 09:23:46 EST 2010
^C

 

  我们创建的命令列表作为 job 2 运行,其 PID 为 4856。每隔两秒钟将运行 date 命令,并且将日期和时间打印在终端窗口上。您输入的内容将突出显示。如果您的输入速度很慢,在输入完整的命令之前,您输入的字符就被几行输出隔开了。事实上,您为了将命令列表放到前台而输入的 “f” 和 “g” 相隔好几行。当您最终输入了 fg 命令之后,bash 将显示正在 shell 中运行的命令(即命令列表),该命令仍然每隔两秒钟打印输出结果。

  在将作业放入前台之后,您可以终止它,或者采取其他操作。在本例中,我们使用 Ctrl-c 终止时钟。

  您可能想问为什么该作业为 job 2。在终止了指针式时钟之后,仅剩下一个运行的作业,它的作业编号为 1。所以将分配下一个可用的作业编号,因此我们的简易时钟为 job 2。

标准 I/O 和后台进程

  在前面的例子中,来自 date 命令的输出被我们输入的 fg 命令产生的字符隔开。这导致一个有趣的问题。如果后台进程需要来自 stdin 的输入时,它会发生什么情况?

  我们将在其下启动后台应用程序的终端进程称为控制终端。除非被重定向到其他地方,否则来自后台进程的 stdout 和 stderr 流将被定向控制终端。类似地,后台任务希望收到来自控制终端的输入,但是控制终端不能将您输入的任何字符定向到后台进程的 stdin。对于这种情况,Bash shell 将暂停进程,从而使它停止执行。您可以将它放到前台并提供必要的输入。清单 7 显示了一个简单的例子,在该例中可以将命令列表放到后台。在片刻之后,按下 Enter 并看到关于进程已被停止的消息。将该命令列表放到前台,添加一行输入,最后按下 Ctrl-d 表示输入文件的结尾。在命令列表运行完成之后将显示我们创建的文件。

清单 7. 等待 stdin

 

ian@attic4:~$ (date; cat - > bginput.txt;date)&
[2] 5070
ian@attic4:~$ Tue Jan 19 10:33:13 EST 2010


[2]+  Stopped                 ( date; cat - > bginput.txt; date )
ian@attic4:~$ 
ian@attic4:~$ fg
( date; cat - > bginput.txt; date )
some text
				more text
Tue Jan 19 10:33:31 EST 2010
ian@attic4:~$ cat bginput.txt 
some text
more text

 

在注销之后运行进程

  在实际操作中,您可能想要将后台进程的标准 I/O 流重定向到文件。这涉及到另一个问题:如果控制终端关闭或用户注销,进程会发生什么情况?答案取决于所使用的 shell。如果 shell 发送 SIGHUP(或 hangup)信号,那么很可能导致应用程序关闭。我们将在稍后讨论信号,现在考虑解决该问题的另一种方法。

nohup

  nohup 命令用于启动一个忽略 hangup 信号的命令,并且将 stdout 和 stderr 附加到文件。默认的文件为 nohup.out 或 $HOME/nohup.out。如果文件不可被写入,将不运行命令。如果您想要将输出指定到其他位置,那么重定向 stdout 或 stderr,参见文章 “学习 Linux,101:流、管道和重定向”。

  nohup 命令将不执行管道线或命令列表。您可以将管道线或列表保存在一个文件中,然后使用 sh(默认 shell)或 bash 命令运行它。本系列的另一篇文章将显示如何让脚本文件变成可执行文件,但是在本文中我们通过 sh 或 bash 命令运行脚本。清单 8 显示了如何为我们的简易数字时钟准备脚本。将时间写到文件中用途不大,并且会造成文件不断变大,因此我们将时钟设置为每 30 秒钟更新一次,而不是每秒钟更新一次。

清单 8. 在脚本中结合使用 nohup 和命令列表

 

ian@attic4:~$ echo "while sleep 30; do date;done">pmc.sh 
ian@attic4:~$ nohup sh pmc.sh&
[2] 5485
ian@attic4:~$ nohup: ignoring input and appending output to `nohup.out'

ian@attic4:~$ nohup bash pmc.sh&
[3] 5487
ian@attic4:~$ nohup: ignoring input and appending output to `nohup.out'

 

  如果我们显示 nohup.out 的内容,我们将看到一些行,并且每个行的出现都比它前面的第二个行晚 30 秒,如清单 9 所示。

清单 9. nohup 进程的输出

 

ian@attic4:~$cat nohup.out
Tue Jan 19 15:01:12 EST 2010
Tue Jan 19 15:01:26 EST 2010
Tue Jan 19 15:01:44 EST 2010
Tue Jan 19 15:01:58 EST 2010
Tue Jan 19 15:02:14 EST 2010
Tue Jan 19 15:02:28 EST 2010
Tue Jan 19 15:02:44 EST 2010
Tue Jan 19 15:02:58 EST 2010

 

  老版本的 nohup 不将状态消息写到控制终端,因此如果您做错了事情,很难立即发现。如果您将 stdout 和 stderr 重定向到自己选择的文件,您将看到老版本中出现的行为。使用 . 发出命令比输入 sh 或 bash 更加容易。清单 10 显示了按照旧方式使用 nohup 会发生什么情况,但同时重定向了 stdout 和 stderr。在输入命令之后,您将看见一条消息,它表明启动的 job 4 的 PID 为 5853。但是,再次按 Enter 将看到另一条,表明该作业已终止,退出码为 126。

清单 10. 以错误的方式使用 nohup

 

ian@attic4:~$ nohup . pmc.sh >mynohup.out 2>&1 &
[4] 5853
ian@attic4:~$ 
[4]+  Exit 126                nohup . pmc.sh > mynohup.out 2>&1

  清单 11 显示了 mynohup.out 的内容。该内容没有特别之处。您使用 nohup 来在后台运行命令,并使用 source (.) 从文件运行读取命令,并在当前的 shell 中运行这些命令。这里需要记住的是,您可能需要按下 Enter 以允许 shell 显示后台作业退出状态,或者需要查看 nohup 的输出文件,看看哪里出错了。

清单 11. 来自 nohup 的隐藏消息

 

 

ian@attic4:~$ cat mynohup.out
nohup: ignoring input
nohup: cannot run command `.': Permission denied

 

  现在,让我们将话题转向进程的状态。如果您在此时想休息一下,那么请不要离开太久,因为您的两个作业在文件系统中创建的文件会不断变大。您可以使用 fg 命令来将它们放到前台,然后使用 Ctrl-c 终止它们。不过,如果您让它们多运行一段时间,将了解监控它们并与它们交互的其他方法。

 


 

监控进程

  我们在前面简单介绍了 jobs 命令,并看到了如何使用它列出作业的 Process ID(或 PID)。

ps

  我们还可以使用另一个命令 ps 来显示进程状态信息的不同部分。记住,“ps” 是 “process status” 的首字母缩写。ps 命令接受 0 个或多个 PID 作为参数并显示相关联的进程状态。如果我们将 jobs 命令与 -p 选项一起使用,输出结果将是每个作业的 process group leader 的 PID。我们将使用该输出作为 ps 命令的参数,如清单 12 所示。

清单 12. 后台进程的状态

 

ian@attic4:~$ jobs -p
3878
5485
5487
ian@attic4:~$ ps $(jobs -p)
  PID TTY      STAT   TIME COMMAND
 3878 pts/1    S      0:06 xclock -d -update 1
 5485 pts/1    S      0:00 sh pmc.sh
 5487 pts/1    S      0:00 bash pmc.sh

 

  如果您使用不带任何选项的 ps 命令,您将看到一个以您的终端作为控制终端的进程列表,如清单 13 所示。注意,该列表中不出现 pmc.sh 命令,但稍后您将看到为什么会这样。

清单 13. 使用 ps 命令显示状态

 

ian@attic4:~$ ps
  PID TTY          TIME CMD
 2643 pts/1    00:00:00 bash
 3878 pts/1    00:00:06 xclock
 5485 pts/1    00:00:00 sh
 5487 pts/1    00:00:00 bash
 6457 pts/1    00:00:00 sleep
 6467 pts/1    00:00:00 sleep
 6468 pts/1    00:00:00 ps

 

  可以通过几个选项控制所显示的信息,包括 -f (full),-j (jobs) 和 -l (long)。如果您不指定任何 PID,那么另一个比较有用的选项是 --forest,它以树结构的形式显示命令,以及每个进程对应的父进程。尤其是,您将看到前一个清单的 sleep 命令是您在后台运行的脚本的子进程。如果您刚好在不同的时间运行该命令,您将看到 date 命令列出在进程状态中,但对于该脚本,发生这种情况的几率不大。我们在清单 14 中显示其中一些选项。

清单 14. 更多状态信息

 

ian@attic4:~$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
ian       2643  2093  0 Jan18 pts/1    00:00:00 bash
ian       3878  2643  0 09:17 pts/1    00:00:06 xclock -d -update 1
ian       5485  2643  0 15:00 pts/1    00:00:00 sh pmc.sh
ian       5487  2643  0 15:01 pts/1    00:00:00 bash pmc.sh
ian       6635  5485  0 15:41 pts/1    00:00:00 sleep 30
ian       6645  5487  0 15:42 pts/1    00:00:00 sleep 30
ian       6647  2643  0 15:42 pts/1    00:00:00 ps -f
ian@attic4:~$ ps -j --forest
  PID  PGID   SID TTY          TIME CMD
 2643  2643  2643 pts/1    00:00:00 bash
 3878  3878  2643 pts/1    00:00:06  \_ xclock
 5485  5485  2643 pts/1    00:00:00  \_ sh
 6657  5485  2643 pts/1    00:00:00  |   \_ sleep
 5487  5487  2643 pts/1    00:00:00  \_ bash
 6651  5487  2643 pts/1    00:00:00  |   \_ sleep
 6658  6658  2643 pts/1    00:00:00  \_ ps

 

  您已经具备一些使用 jobs 和 ps 命令监控进程的基本工具,在学习如何选择和排列进程之前,让我们简单看看其他两个监控命令。

free

  free 命令显示系统的空闲内存和已用内存。默认情况下,使用的单位为千字节,但您可以使用选项 -b 替换为字节,使用 -k 替换为千字节,使用 -m 替换为兆字节,或使用 -g 替换为千兆字节。-t 选项显示整个行,带一个值的 -s 选项以指定的频率刷新信息。刷新时间的单位为秒,但可能是浮点值。清单 15 显示了两个例子。

清单 15. 使用 free 命令

 

ian@attic4:~$ free
             total       used       free     shared    buffers     cached
Mem:       4057976    1543164    2514812          0     198592     613488
-/+ buffers/cache:     731084    3326892
Swap:     10241428          0   10241428
ian@attic4:~$ free -mt
             total       used       free     shared    buffers     cached
Mem:          3962       1506       2456          0        193        599
-/+ buffers/cache:        713       3249
Swap:        10001          0      10001
Total:       13964       1506      12457

 

uptime

  uptime 命令在一行内显示当前时间,系统运行时间,当前登录的用户,以及过去 1 分钟、5 分钟和 15 分钟系统的平均负载。清单 16 显示了一个例子。

清单 16. 显示正常运行时间信息

 

ian@attic4:~$ uptime
 17:41:17 up 20:03,  5 users,  load average: 0.00, 0.00, 0.00

 

根据需要选择和排列进程的显示方式

使用 ps

  到目前为止所讨论的 ps 命令仅列出从终端会话启动的进程(注意清单 14 中的第二个例子的 SID 列,即会话 ID 列)。要通过控制终端查看所有进程,使用 -a 选项。-x 选项显示不使用控制终端的进程,-e 选项显示每一个进程的信息。清单 17 显示带控制终端的所有进程的完整格式。

清单 17. 显示其他进程

 

ian@attic4:~$ ps -af
UID        PID  PPID  C STIME TTY          TIME CMD
ian       3878  2643  0 09:17 pts/1    00:00:06 xclock -d -update 1
ian       5485  2643  0 15:00 pts/1    00:00:00 sh pmc.sh
ian       5487  2643  0 15:01 pts/1    00:00:00 bash pmc.sh
ian       7192  5485  0 16:00 pts/1    00:00:00 sleep 30
ian       7201  5487  0 16:00 pts/1    00:00:00 sleep 30
ian       7202  2095  0 16:00 pts/0    00:00:00 ps -af

 

  注意在 TTY 列中列出的控制终端。为了获取这个列表,我已切换到原先打开的终端窗口(pts/0),因此 ps -af 命令在 pts/0 下运行,尽管为本文创建的命令在 pts/1 下运行。

  有许多针对 ps 的选项,包括控制显示哪些字段和以何种方式显示的选项。其他选项控制选择显示的进程,例如,为特定的用户(-u)或命令(-C)选择这些进程。在清单 18 中,列出了所有运行 getty 命令的进程;我们使用 -o 选项来自指定将要显示的列。我们将 user 选项添加到单纯使用 ps 获取到的常规列表,因此您可以看到哪个用户正在运行 getty。

清单 18. 谁正在运行 getty 命令?

ian@attic4:~$ ps -C getty -o user,pid,tty,time,comm
USER       PID TT           TIME COMMAND
root      1192 tty4     00:00:00 getty
root      1196 tty5     00:00:00 getty
root      1209 tty2     00:00:00 getty
root      1219 tty3     00:00:00 getty
root      1229 tty6     00:00:00 getty
root      1731 tty1     00:00:00 getty

  有时您需要根据特定的字段对输出进行排序,您也可以使用 --sort 选项指定要排序的字段来实现该目的。默认值为以升序的方式进行排序(+),但您也可以指定以降序的方式进行排序(-)。清单 19 显示了最终的 ps 例子,其中使用作业的格式列出了所有进程,并且根据会话 ID 和命令名对输出进程排序。首先,我们使用默认的排序;其次,我们显式地指定这两种排序方式。

清单 19. 对来自 ps 命令的输出进行排序

ian@attic4:~$ ps -aj --sort -sid,+comm
  PID  PGID   SID TTY          TIME CMD
 5487  5487  2643 pts/1    00:00:00 bash
 9434  9434  2643 pts/1    00:00:00 ps
 5485  5485  2643 pts/1    00:00:00 sh
 9430  5485  2643 pts/1    00:00:00 sleep
 9433  5487  2643 pts/1    00:00:00 sleep
 3878  3878  2643 pts/1    00:00:10 xclock
 8019  8019  2095 pts/0    00:00:00 man
 8033  8019  2095 pts/0    00:00:00 pager
ian@attic4:~$ ps -aj --sort sid,comm
  PID  PGID   SID TTY          TIME CMD
 8019  8019  2095 pts/0    00:00:00 man
 8033  8019  2095 pts/0    00:00:00 pager
 5487  5487  2643 pts/1    00:00:00 bash
 9435  9435  2643 pts/1    00:00:00 ps
 5485  5485  2643 pts/1    00:00:00 sh
 9430  5485  2643 pts/1    00:00:00 sleep
 9433  5487  2643 pts/1    00:00:00 sleep
 3878  3878  2643 pts/1    00:00:10 xclock

  和平常一样,查看手册页详细了解您可以指定多少个选项和字段,或者使用 ps --help 命令了解简要说明。

使用 top

  如果您在一行内多次运行 ps,以便看看发生了什么变化,您可能需要改用 top 命令。它显示持续更新的进程列表和有用的摘要信息。清单 20 显示 top 命令输出的前几行。使用子命令 q 退出 top。

清单 20. 使用 top 显示进程

top - 16:07:22 up 18:29,  5 users,  load average: 0.03, 0.02, 0.00
Tasks: 170 total,   1 running, 169 sleeping,   0 stopped,   0 zombie
Cpu(s):  2.1%us,  0.5%sy,  0.0%ni, 97.4%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   4057976k total,  1543616k used,  2514360k free,   194648k buffers
Swap: 10241428k total,        0k used, 10241428k free,   613000k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 6820 ian       20   0  506m  78m  26m S    1  2.0   0:23.97 firefox
 1381 root      20   0  634m  40m  18m S    1  1.0   2:06.74 Xorg
 2093 ian       20   0  212m  15m  10m S    1  0.4   0:13.53 gnome-terminal
 6925 ian       20   0 1118m 298m  19m S    1  7.5   1:07.04 java
 6855 ian       20   0 73416  11m 8808 S    1  0.3   0:05.01 npviewer.bin
 7351 ian       20   0 19132 1364  980 R    0  0.0   0:00.07 top
    1 root      20   0 19584 1888 1196 S    0  0.0   0:00.74 init
    2 root      15  -5     0    0    0 S    0  0.0   0:00.01 kthreadd

top 命令有许多子命令,其中开始学习时最有用的子命令为:

h
  获得帮助
q
  退出 top 命令
f
  在显示结果中添加或删除字段
o
  显示顺序
F
  选择需要根据其进行排序的字段

  查看手册页详细了解 top 的各种选项,包括如何根据内存使用或其他标准进行排序。清单 21 显示了一个根据虚拟内存使用量以降序的方式进行排序的例子。

清单 21. 对 top 命令的输出结果进行排序

top - 16:21:48 up 18:43,  5 users,  load average: 0.16, 0.06, 0.01
Tasks: 170 total,   3 running, 167 sleeping,   0 stopped,   0 zombie
Cpu(s):  2.1%us,  0.8%sy,  0.0%ni, 96.6%id,  0.0%wa,  0.0%hi,  0.5%si,  0.0%st
Mem:   4057976k total,  1588940k used,  2469036k free,   195412k buffers
Swap: 10241428k total,        0k used, 10241428k free,   613056k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND            
 6925 ian       20   0 1171m 338m  21m S    0  8.5   1:44.10 java               
 1381 root      20   0  634m  40m  18m S    0  1.0   2:13.63 Xorg                
 6820 ian       20   0  506m  83m  26m S    3  2.1   0:51.28 firefox            
 2004 ian       20   0  436m  23m  15m S    0  0.6   0:01.55 nautilus           
 2031 ian       20   0  419m  13m  10m S    0  0.3   0:00.11 evolution-alarm    
 2118 ian       20   0  372m  10m 7856 S    0  0.3   0:00.06 evolution-data-    
 2122 ian       20   0  344m  13m  10m S    0  0.3   0:00.10 evolution-excha    
 2001 ian       20   0  331m  22m  14m S    0  0.6   0:13.61 gnome-panel        
 1971 ian       20   0  299m 9.9m 7244 S    0  0.3   0:05.00 gnome-settings-    
 1989 ian       20   0  288m  15m  11m S    0  0.4   0:11.95 metacity           
 1954 ian       20   0  265m 5460 3412 S    0  0.1   0:00.28 pulseaudio         

向进程发送信号

  现在,让我们看一下 Linux 信号,它是一种与进程通信的异步方式。我们已经提到 SIGHUP 信号并且使用了 Ctrl-c 和 Ctrl-z 组合键,它们是向进程发送信号的其他方式。发送信号的常见方式是使用 kill 命令。

使用 kill 命令发送信号

  kill 命令将信号发送到指定的作业或进程。清单 22 显示使用 SIGTSTP 和 SIGCONT 信号来停止和恢复后台作业。使用 SIGTSTP 信号等效于使用 fg 命令将作业放到前台并使用 Ctrl-z 暂停它。使用 SIGCONT 类似于使用 bg 命令。

清单 22. 停止和重新启动后台作业

ian@attic4:~$ kill -s SIGTSTP %1

[1]+  Stopped                 xclock -d -update 1
ian@attic4:~$ jobs -l
[1]+  3878 Stopped                 xclock -d -update 1
[2]   5485 Running                 nohup sh pmc.sh &
[3]-  5487 Running                 nohup bash pmc.sh &
ian@attic4:~$ kill -s SIGCONT 3878
ian@attic4:~$ jobs -l
[1]   3878 Running                 xclock -d -update 1 &
[2]-  5485 Running                 nohup sh pmc.sh &
[3]+  5487 Running                 nohup bash pmc.sh &

  在本例中,我们使用作业指示 (%1) 停止 xclock 进程,然后使用进程 ID(PID)重新启动(继续)它。如果您停止 job %2,然后使用 tail 及其后面的 -f 选项,您将看到仅有一个进程正在更新 nohup.out 文件。

  您可以使用 kill -l 在系统中显示许多其他信号。其中一些信号用于报告错误,比如非法操作代码,浮点异常,或试图访问进程无权访问的内存。注意,信号也有编号(比如 20)和名称(比如 SIGTSTP)。您可以使用连字符 (-) 前面的编号,也可以使用 -s 选项和信号名。在我的系统中,我使用 kill -20,而不是 kill -s SIGTSTP。在确定哪个编号对应哪个信号之前,您应该检查系统中信号的编号。

信号处理程序和进程终止

  您已经看到使用 Ctrl-c 可以终止进程。事实上,它向进程发送一个 SIGINT(或中断)信号。如果您使用不带任何信号名的 kill,它将发送一个 SIGTERM 信号。在大多数情况下,这两个信号是等效的。

  您已经看到 nohup 命令可以让进程避开 SIGHUP 信号。一般情况下,进程可以实现一个信号处理程序 来捕捉 信号。因此进程可以实现信号处理程序来捕捉 SIGINT 或 SIGTERM。因为信号处理程序知道发送的信号是什么,所以它可能选择忽略 SIGINT,并且在收到(比如)SIGTERM 时才终止。清单 23 显示了如何将 SIGTERM 信号发送到 job %2。注意,在发送信号之后,进程状态立即显示为 “Terminated”。如果我们使用 SIGINT,将显示为 “Interrupt”。在片刻之后,将开始清除进程,作业也不再出现在作业列表中。

清单 23. 使用 SIGTERM 终止进程

ian@attic4:~$ kill -s SIGTERM %2
ian@attic4:~$ 
[2]-  Terminated              nohup sh pmc.sh
ian@attic4:~$ jobs -l
[1]-  3878 Running                 xclock -d -update 1 &
[3]+  5487 Running                 nohup bash pmc.sh &

  信号处理程序给进程提供了很大的灵活性。进程可以完成其常规工作,并且为了实现特定目的可以被信号中断。除了允许进程捕捉终止请求和采取可能的行动(比如关闭正在进行的文件或检查点事务)之外,信号还通常用于告诉守护进程重新读取其配置文件和重启操作。您在添加新的打印程序时可能要更改网络参数或 line printer daemon (lpd),这时可能需要进行该操作。

无条件终止进程

  有一些信号是无法捕获的,比如某些硬件异常。您最常用的 SIGKILL 就不能被信号处理程序捕捉到,因此需要无条件终止它。总而言之,仅当所有办法都无法终止进程时,才选择无条件终止它。


注销和 nohup

  还记得吗,使用 nohup 允许您在注销之后仍然让进程继续运行。让我们先注销然后再次登录。在登录之后,使用 jobs 和 ps 检查仍然在运行的简易时钟进程,和前面所做的一样。该操作的输出如清单 24 所示。

清单 24. 重新登录

ian@attic4:~$ jobs -l
ian@attic4:~$ ps -a
  PID TTY          TIME CMD
10995 pts/0    00:00:00 ps

  这次我们在 pts/0 中运行,但仅出现 ps 命令,而没有出现我们的作业。不过,它们并没有丢失。假设您不记得是否终止了使用 bash 启动的 nohup 作业或其他使用 bash 启动的作业。您在前面了解到如何找到运行 getty 命令的进程,因此您可以使用相同的方法来显示 SID、PID、PPID 和命令字符串。然后,您可以使用 -js 选项显示会话中的所有进程。清单 25 显示了结果。想想其他您曾用于找到这些进程的方法,比如搜索用户名然后使用 grep 进行过滤。

清单 25. 找出丢失的命令

ian@attic4:~$ ps -C bash -C sh -o pid,sid,tname,cmd
  PID   SID TTY      CMD
 5487  2643 ?        bash pmc.sh
 7050  7050 pts/3    -bash
10851 10851 pts/0    bash
ian@attic4:~$ ps -js 2643
  PID  PGID   SID TTY          TIME CMD
 5487  5487  2643 ?        00:00:00 bash
11197  5487  2643 ?        00:00:00 sleep

  注意,pmc.sh 仍然运行,但现在控制 TTY 多了一个问号 (?)。

  既然您现在已经学会了如何终止进程,您应该能够通过 PID 和 kill 命令终止仍然在运行的简易时钟进程。


参考资料

学习

  • 使用 学习 Linux,101:LPIC-1 路线图 找到相关的 developerWorks 文章,它们能够帮助您准备基于 2009 年 4 月的考核目标的 LPIC-1 认证考试。
  • LPIC Program 站点上可以找到针对 Linux Professional Institute's Linux 系统管理认证的三个级别的详细考核目标、任务列表和样例问题。尤其要查看针对 LPI 考试 101LPI 考试 102 的 2009 年 4 月份考核目标。要经常查看 LPIC Program 站点了解最新的考核目标。
  • 在 developerWorks 上查看完整的 LPI 考试准备系列,学习 Linux 基础知识并根据 2009 年 4 月份之前的 LPI 考试目标准备系统管理员认证考试。
  • 在 “Linux 开发新手基本任务”(developerWorks,2005 年 3 月)中了解如何打开终端窗口或 shell 提示符等。
  • Linux 文档项目 提供各种有用的文档,尤其是它的 HOWTO 文档。

关于作者

Ian Shields 参与了 developerWorks Linux 专区的许多 Linux 项目。他是 IBM 北卡罗来纳州 Research Triangle Park 的一名高级程序员。他于 1973 年作为一名系统工程师加入 IBM 位于澳大利亚堪培拉的子公司。之后,在加拿大蒙特利尔和北卡罗莱那州 RTP 从事通信系统和普及运算。他拥有多项专利。他毕业于 Australian National University,本科学位是纯粹数学和哲学。他拥有北卡罗来纳州立大学的计算机硕士和博士学位。

联系 Ian

Ian 是我们最受欢迎并且很多产的作者之一。查看 Ian 的个人资料 并与他和 My developerWorks 上的其他作者和读者联系。

本文来自

  http://www.ibm.com/developerworks/cn/linux/l-lpic1-v3-103-5/index.html
  发布日期:2010 年 3 月 09 日
  级别:中级
  其他语言版本:英文

发表评论 评论 (2 个评论)

回复 SchrodingerCat 2010-3-21 01:02
很好,收藏
回复 baiuterfk 2010-3-31 22:33
系列学习了

facelist

你需要登录后才可以评论 登录 | 加入

无觅相关文章插件