本节讨论初级管理(LPIC-1)考试 101 的主题 1.103.5 的内容。这个主题的权值是 5。
在本节中,学习以下主题:
- 前台和后台作业
- 启动没有用于 I/O 的终端的进程
- 监视和显示进程
- 向进程发送信号
- 识别和杀死进程
显然,除了正在运行的终端程序之外,计算机上还运行着许多程序。如果正在使用图形桌面,可能会同时打开多个终端窗口,可能打开文件浏览器、互联网浏览器、游戏、电子表格或其他应用程序。到目前为止,我们的示例都是在终端窗口中输入命令。命令运行,我们等待它完成,在此之前我们不能做其他任何事情。在 使用命令行 一节中,我们遇到了显示进程状态的 ps 命令,并看到进程有进程 ID(PID)和父进程 ID(PPID)。在本节中,学习如何使用终端窗口同时执行多个任务。
前台和后台作业
在终端窗口中运行命令时,比如在此之前我们给出的那些命令示例,是在前台 运行它。我们的命令都运行得非常快,所以进程不会长期存在。为了研究长期运行的进程,假设我们正在运行一个图形桌面,希望在桌面上显示一个数字化时钟。大多数桌面已经有了这种时钟,这没关系,我们只是以此作为示例。
如果安装了 X Window 系统,就可能有 xclock 或 xeyes 这样的实用程序。这两种程序对于这个练习都适用,但是我们使用 xclock。手册页指出,可以使用以下命令在图形桌面上启动一个数字化时钟fGMLinux联盟
fGMLinux联盟
xclock -d -update 1 fGMLinux联盟
fGMLinux联盟
-update 1 部分要求每秒进行一次更新,如果没有这个选项,时钟每分钟只更新一次。现在在一个终端窗口中运行这个命令。应该会看到图 2 所示的时钟,终端窗口的内容看起来应该像清单 82 这样。如果您没有 xclock 或 X Window 系统,我们稍后会解释如何用终端创建一个简单的数字化时钟,所以您可以先学下去,在创建了那个时钟之后,用它做这些练习。
fGMLinux联盟
图 2. 用 xclock 显示数字化时钟fGMLinux联盟
fGMLinux联盟
fGMLinux联盟
清单 82. 启动 xclock
[ian@echidna ian]$ xclock -d -update 1
|
不幸的是,终端窗口不再有提示符,所以确实需要重新获得控制。幸运的是,bash shell 有一个暂停 键,Ctrl-z。按下这个组合键会重新出现终端提示符,如清单 83 所示。
fGMLinux联盟
清单 83. 用 Ctrl-z 暂停 xclock
[ian@echidna ian]$ xclock -d -update 1
[1]+ Stopped xclock -d -update 1
[ian@echidna ian]$
|
时钟仍然在桌面上,但是已经停止运行了。它确实已经暂停了。实际上,如果将另一个窗口拖过时钟上面,它甚至不会重新绘制。还会看到一个终端输出消息,表示 “[1]+ Stopped”。这个消息中的 1 是作业号。可以通过输入 fg %1 重新启动时钟。还可以使用命令名或命令名的一部分,即 fg %xclock 或 fg %?clo。最后,如果使用没有参数的 fg,那么就会重新启动最近停止的作业,在这个示例中就是作业 1。用 fg 进行重新启动也将作业带回前台,并不再有 shell 提示符。需要做的事是将这个作业放到后台;bg 命令可以完成这个任务,它采用与 fg 命令相同的作业指定方式。清单 84 显示如何使用两种形式的 fg 命令将 xclock 作业带回前台。可以再次暂停它并将它放到后台;时钟继续运行,同时您可以在终端中做其他工作。
fGMLinux联盟
清单 84. 将 xclock 放到后台
[ian@echidna ian]$ fg %1
xclock -d -update 1
[1]+ Stopped xclock -d -update 1
[ian@echidna ian]$ fg %?clo
xclock -d -update 1
[1]+ Stopped xclock -d -update 1
[ian@echidna ian]$ bg
[1]+ xclock -d -update 1 &
[ian@echidna ian]$
|
使用 “&”
您可能会注意到,在将 xclock 作业放到后台时,消息不再指出 “Stopped”,而是以一个 & 结束。实际上,根本不需要为了将进程放到后台而暂停它。只需要将一个 & 放在命令后面,shell 就会在后台启动命令。我们使用这种方法启动一个模拟时钟,它具有小麦背景和红色的指针。应该会看到图 3 这样的时钟和清单 85 这样的终端输出。
fGMLinux联盟
图 3. 用 xclock 显示模拟时钟fGMLinux联盟
fGMLinux联盟
fGMLinux联盟
清单 85. 用 & 在后台启动 xclock
[ian@echidna ian]$ xclock -bg wheat -hd red -update 1&
[2] 5659
|
注意,这一次消息有点儿不一样。它代表一个作业号和一个进程 id(PID)。稍后会讨论 PID 和状态。现在,使用 jobs 命令了解正在运行什么作业。添加 -l 选项来列出 PID,会看到作业 2 的 PID 确实是 5659,见清单 86。还要注意,作业 2 在作业号旁边有一个加号(+),这表示它是当前作业。如果使用 fg 命令时没有指定作业,这个作业就会转到前台。
fGMLinux联盟
清单 86. 显示作业和进程信息
[ian@echidna ian]$ jobs -l
[1]- 4234 Running xclock -d -update 1 &
[2]+ 5659 Running xclock -bg wheat -hd red -update 1 &
|
在解决与后台作业相关的其他问题之前,我们先创建一个简单的数字化时钟。使用 sleep 命令产生两秒的延迟,并使用 date 命令打印当前日期和时间。将这些命令放在一个 while 循环中,并使用 do/done 块创建一个无限循环。最后,将所有这些放在圆括号中构成命令列表,并使用 & 让整个命令列表在后台运行。
fGMLinux联盟
清单 87. 简单的数字化时钟
[ian@echidna ian]$ (while sleep 2; do date;done) &
[1] 16291
[ian@echidna ian]$ Thu Nov 10 22:58:02 EST 2005
Thu Nov 10 22:58:04 EST 2005
Thu Nov 10 22:58:06 EST 2005
Thu Nov 10 22:58:08 EST 2005
fThu Nov 10 22:58:10 EST 2005 Thu Nov 10 22:58:12 EST 2005
gThu Nov 10 22:58:14 EST 2005
( while sleep 2; do
date;
done )
Thu Nov 10 22:58:16 EST 2005
Thu Nov 10 22:58:18 EST 2005
|
这个命令列表作为作业 1 运行,PID 是 16291。每隔两秒,date 命令运行并在终端上打印一个日期和时间。用户的输入以粗体显示。对于输入很慢的人,在输入一条完整的命令之前,这个命令列表可能已经产生了几行输出,所以输入的字符可能与输出混在一起。实际上,我们输入的 ‘f’‘g’ 是 fg 命令,用于将这个命令列表带到前台,但是这个命令被两行输出分开了。当最终输入完 fg 命令时,bash 显示正在 shell 中运行的命令,也就是这个命令列表,之后仍然每两秒打印一次时间。
成功地将作业带到后台之后,可以终止(即杀死)它,或者采取某些其他操作。在这个示例中,使用 Ctrl-c 终止时钟。
标准 IO 和后台进程
在前面的示例中,date 命令的输出与 fg 命令的回显字符混在一起。这就产生了一个有意思的问题。如果进程需要来自 stdin 的输入,那么会怎么样?
用来启动后台应用程序的终端进程称为控制终端。除非被重定向到其他地方,否则来自后台进程的 stdout 和 stderr 流会输出到控制终端。同样,后台任务期望从控制终端获得输入,但是控制终端无法将您输入的字符转发给后台进程的 stdin。在这种情况下,bash shell 暂停进程,这样它就不再执行了。可以将它带到前台并提供必要的输入。清单 88 演示了一种简单的情况。可以将一个命令列表放到后台执行。过了一会儿,按 Enter,进程停止。将它带到前台,提供一行输入,最后按 Ctrl-d 表示输入文件结束。命令列表完成,我们显示创建的文件。
fGMLinux联盟
清单 88. 等待 stdin
[ian@echidna ian]$ (date; cat - >bginput.txt; date)&
[1] 18648
[ian@echidna ian]$ Fri Nov 11 00:03:28 EST 2005
[1]+ Stopped ( date; cat - >bginput.txt; date )
[ian@echidna ian]$ fg
( date; cat - >ginput.txt; date )
input data
Fri Nov 11 00:03:53 EST 2005
[ian@echidna ian]$ cat bginput.txt
input data
|
没有终端的作业
在实践中,可能希望让后台进程的标准 IO 流重定向到文件或者来自文件。有另一个相关问题;如果控制终端关闭了或用户注销了,那么进程会怎么样?答案取决于使用的 shell。如果 shell 发送 SIGHUP(或 hangup)信号,那么应用程序可能关闭。我们稍后讨论信号,但是目前考虑解决这个问题的另一种方式。
nohup
nohup 命令用于启动一个命令,它将忽略 hangup 信号并将 stdout 和 stderr 附加到文件。默认文件是 nohup.out 或 $HOME/nohup.out。如果文件不可写,那么命令将不运行。如果希望将输出发送到别处,那么对 stdout 或 stderr 进行重定向。
nohup 的另一个特点是,它不执行管道或命令列表。在 对标准 IO 进行重定向 一节中,我们看到了如何将一组命令保存在 shell 脚本中并引用(source)它。可以将管道或列表保存在文件中,然后使用 sh(默认 shell)或 bash 命令运行它,但是不能使用前面示例中使用的 . 或 source 命令。本系列中的下一个教程(针对主题 104,讨论设备、Linux 文件系统和 Filesystem Hierarchy Standard)将解释如何使脚本文件可执行,但是目前只通过引用(source)或者通过使用 sh 或 bash 命令来运行脚本。清单 89 显示如何用脚本运行刚才创建的数字化时钟。但是,将时间写到文件中其实没什么用,而且文件会随着脚本运行而增大,所以将时钟设置为每 30 秒更新一次而不是每秒一次。
fGMLinux联盟
清单 89. 使用 nohup 运行脚本中的命令列表
[ian@echidna ian]$ echo "while sleep 30; do date;done">pmc.sh
[ian@echidna ian]$ nohup . pmc.sh&
[1] 21700
[ian@echidna ian]$ nohup: appending output to `nohup.out'
[1]+ Exit 126 nohup . pmc.sh
[ian@echidna ian]$ nohup sh pmc.sh&
[1] 21709
[ian@echidna ian]$ nohup: appending output to `nohup.out'
[ian@echidna ian]$ nohup bash pmc.sh&
[2] 21719
[ian@echidna ian]$ nohup: appending output to `nohup.out'
|
如果显示 nohup.out 的内容,会看到第一行说明为什么在第一次尝试时会得到退出码 126。后续的行是来自在后台运行的两个 pmc.sh 版本的输出。清单 90 显示了 nohup 的输出。
fGMLinux联盟
清单 90. nohup 进程的输出
[ian@echidna ian]$ cat nohup.out
/bin/nice: .: Permission denied
Fri Nov 11 15:30:03 EST 2005
Fri Nov 11 15:30:15 EST 2005
Fri Nov 11 15:30:33 EST 2005
Fri Nov 11 15:30:45 EST 2005
Fri Nov 11 15:31:03 EST 2005
|
现在,我们来讨论进程的状态。停下来思考一下,现在有了两个作业,它们在文件系统中创建不断增大的文件。可以使用 fg 命令将它们带到前台,然后使用 Ctrl-c 终止它,但是如果让它们运行时间长一些,我们就可以看看监视它们和与它们进行交互的其他方式。fGMLinux联盟
Linux联盟收集整理 ,转贴请标明原始链接,如有任何疑问欢迎来本站Linux论坛讨论