这篇文章翻译自: http://linuxcommand.org/lts0080.php
上一课我们看到了Linux作为一个多用户系统的复杂之处(权限), 这一课我们来学习Linux的多任务特性和在命令行界面的操作方法.
如任何多任务系统一样, Linux执行的是多个同步的进程. 好吧, 它们只是看上去同步罢了. 实际上, 一个单处理器电脑在同一时间只能运行一个进程, 但Linux内核想办法给每个进程都有时间片轮流执行, 这样看上去它们就是同步的了.
我们有几个控制进程的命令:
-
ps
- 把进程系统的列出 (注: 只有ps -A
能列出系统所有进程,ps
只能列出当前进程和它的子进程) -
kill
- 发送一个信号给进程 (通常用作杀进程) -
jobs
- 另一种方法, 列出你的进程 -
bg
- 将一个进程放到后台执行 -
fg
- 讲一个进程拉到前台执行
实际例子
虽说这个话题有那么点低级, 但是对于那些长期用图形界面的普通用户来说是很有实际意义的. 你可能不知道, 大多(即便不是所有)图形界面程序都能在命令行启动. 例如, 有一个带有X Windows系统的小程序xload
, 它能显示一张图形以代表系统启动. 你可以键入下面这些来启动它:
shell
[me@linuxbox me]$ xload
请留意到xload窗口出现并且显示了图形, 同时也该留意到提示符在程序启动之后不再出现. shell在等待(wait()
)程序完结, 然后才把控制权交还给你. 如果你关掉xload窗口, xload
程序终止, 提示符重新出现.
把程序放到后台
好, 为了改善生活, 我们要重新启动xload, 不过这次我们把它放到后台, 这样提示符就会回来了. 要做到这一点, 这样执行就好:
shell
[me@linuxbox me]$ xload & [1] 1223 [me@linuxbox me]$
在这个例子中, 提示符返回了, 因为程序被放到了后台.
现在想象一下你在执行一个后台的程序时, 把&符号打漏了. DON'T PANIC, 还是有希望的. 你先按下 Control-Z, 这样程序挂起. 程序还是在的, 只不过被闲置着. 要想在后台恢复它的运行, 运行bg
(background的缩写):
shell
[me@linuxbox me]$ xload [2]+ Stopped xload [me@linuxbox me]$ bg [2]+ xload &
列出你的进程
现在我们把一个进程放到了后台, 这样列出我们启动了的进程就变得相当有用. 我们可以用jobs
或者ps
来完成这一点:
shell
[me@linuxbox me]$ jobs [1]+ Running xload & [me@linuxbox me]$ ps PID TTY TIME CMD 1211 pts/4 00:00:00 shell 1246 pts/4 00:00:00 xload 1247 pts/4 00:00:00 ps [me@linuxbox me]$
人被杀, 就会死
设想有个程序无响应了(hmmm...Netscape浮现在脑中 ;-); 怎么把它弄走? 当然, 你可以用kill
命令. 我们来在xload上试试刀. 首先你得得到那个将被杀的程序的标识. 你可以用ps或者jobs, 用jobs得到job号, 用ps得到进程id (PID). 我们两个都试一下:
shell
[me@linuxbox me]$ xload & [1] 1292 [me@linuxbox me]$ jobs [1]+ Running xload & [me@linuxbox me]$ kill %1 [me@linuxbox me]$ xload & [2] 1293 [1] Terminated xload [me@linuxbox me]$ ps PID TTY TIME CMD 1280 pts/5 00:00:00 shell 1293 pts/5 00:00:00 xload 1294 pts/5 00:00:00 ps [me@linuxbox me]$ kill 1293 [2]+ Terminated xload [me@linuxbox me]$
就算是神, 我也杀给你看! (误
"kill"命令通常用作杀进程, 而它的的作用其实是向进程发送一个信号. 大多数时候信号就是告诉程序"好了别再运行了", 然后没有然后了. 程序监听和回应操作系统信号(如果它们写得好), 大多数时候都是为了能有一个更优雅的终止方式(死法). 例如, 一个文本编辑器可能要监听用户是不是要登出, 或者电脑是不是要关机. 当它收到这些信号, 它就得在退出之前保存工作. kill命令能法送一大堆不同的信号呢, 键入:
shell
kill -l
就会列出它支持的信号. 大多都比较晦涩, 不过有几个是蛮常用:
信号
Num | Name | Description |
---|---|---|
1 | SIGHUP | 挂起信号. 程序可以监听并决定是否挂起(注: 见nohup命令和Control-Z) |
2 | SIGINT | 中断信号. 这个信号希望让进程中断的, 当然最终的行为由进程自己决定. 你可以在终端按Control-C(aka, 键盘中断)来发出这个信号. |
15 | SIGTERM | 终止信号. 这个信号希望让进程终止的, 最终的行为仍由进程自己决定. 这是kill命令默认发出的信号. |
9 | SIGKILL | 杀信号. 这个信号用于立即终止进程. 它由内核发出, 无法监听和处理. |
好现在设想你有一个进程已经毫无希望地卡在那里了(比如可怜地Netscape), 你要停掉它, 你该这样做:
- 用ps命令获取它地进程号 (PID).
- 对这个 PID 执行kill.
- 如果进程拒绝终止(比如它忽略了这个信号), 那么就对它发出更加严厉的信号, 直到它停止了.
shell
[me@linuxbox me]$ ps x PID TTY STAT TIME COMMAND 2931 pts/5 SN 0:00 netscape [me@linuxbox me]$ kill -SIGTERM 2931 [me@linuxbox me]$ kill -SIGKILL 2931
这个例子中, 我以一个更加形式化的写法来用kill命令. 在实际应用中, 下面这个更常用, 因为kill默认发出SIGTERM, -信号也可以用数字而不是名字来代替:
shell
[me@linuxbox me]$ kill 2931
如果进程还不终止, 那就用SIGKILL强制终止:
shell
[me@linuxbox me]$ kill -9 2931
原来如此!
这在"Learning the shell"系列课程中的最后一个. 下一个系列, "写shell脚本", 我们将学习如何用shell脚本自动化任务.