DeTechn Blog

Linux 命令行实用命令

进程相关

当程序运行在系统上时,我们称之为进程(process)。想监测这些进程,需要熟悉 ps/top 等命令的用法。ps 命令好比工具中的瑞士军刀,它能输出运行在系统上的所有程序的许多信息。而 top 可以监控当前各个进程的运行状态,以及占用 cpu,内存等系统资源的情况。

ps 查看进程

默认情况下,ps 命令只会显示运行在当前控制台下的属于当前用户的进程。直接执行 ps 命令,可以发现我们只运行了 bash shell(注意,shell 也只是运行在系统上的另一个程序而已)以及 ps 命令本身。可以看到基本输出显示了程序的进程 ID(Process ID,PID)、它们运行在哪个终端(TTY)以及进程已用的 CPU 时间。

Linux 系统中使用的 GNU ps 命令支持 3 种不同类型的命令行参数:


Unix 风格一些常用的参数组合:

$ ps -ef #查看系统上运行的所有进程  -e参数指定显示所有运行在系统上的进程;-f参数则扩展了输出,这些扩展的列包含了有用的信息。
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 11:29 ?        00:00:01 /sbin/init
...

如果想要获得更多的信息,可采用-l 参数,它会产生一个长格式输出。

$ ps -l
F S  UID PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY      TIME   CMD
0 S  500 3081  3080  0  80   0 -  1173 wait pts/0   00:00:00 bash
0 R  500 4463  3081  1  80   0 -  1116 -    pts/0   00:00:00 ps

注意使用了-l 参数之后多出的那些列。


在使用 BSD 参数时,ps 命令会自动改变输出以模仿 BSD 格式。大部分的输出列跟使用 Unix 风格参数时的输出是一样的,只有一小部分不同。

$ ps l
F  UID  PID PPID PRI  NI  VSZ  RSS WCHAN  STAT TTY      TIME COMMAND
0  500 3081 3080  20   0 4692 1432 wait   Ss   pts/0    0:00 -bash
0  500 5104 3081  20   0 4468  844 -      R+   pts/0    0:00 ps l

许多系统管理员都喜欢 BSD 风格的 l 参数。它能输出更详细的进程状态码(STAT 列)。双字符状态码能比 Unix 风格输出的单字符状态码更清楚地表示进程的当前状态。第一个字符采用了和 Unix 风格 S 列相同的值,表明进程是在休眠、运行还是等待。第二个参数进一步说明进程的状态。

从前面的例子可以看出,bash 命令处于休眠状态,但同时它也是一个控制进程(在我的会话中,它是主要进程),而 ps 命令则运行在系统的前台。


最后,GNU 开发人员在这个新改进过的 ps 命令中加入了另外一些参数。其中一些 GNU 长参数复制了现有的 Unix 或 BSD 类型的参数,而另一些则提供了新功能。

可以将 GNU 长参数和 Unix 或 BSD 风格的参数混用来定制输出。GNU 长参数中一个着实让人喜爱的功能就是--forest 参数。它会显示进程的层级信息,并用 ASCII 字符绘出可爱的图表。这种格式让跟踪子进程和父进程变得十分容易。

top 监控进程

ps 命令虽然在收集运行在系统上的进程信息时非常有用,但也有不足之处:它只能显示某个特定时间点的信息。如果想观察那些频繁换进换出的内存的进程趋势,用 ps 命令就不方便了。而 top 命令刚好适用这种情况。top 命令跟 ps 命令相似,能够显示进程信息,但它是实时显示的。

xbren@archlinux:~$ top
top - 00:01:04 up 38 min,  0 users,  load average: 0.52, 0.58, 0.59
Tasks:   4 total,   1 running,   3 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.5 us,  0.8 sy,  0.0 ni, 98.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  16042.5 total,   8472.3 free,   7346.2 used,    224.0 buff/cache
MiB Swap:  49152.0 total,  49099.5 free,     52.5 used.   8565.7 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
    1 root      20   0    9216    660    320 S   0.0   0.0   0:00.18 init
 5115 root      20   0    9308    240    176 S   0.0   0.0   0:00.00 init
 5116 xbren     20   0   19280   4808   4704 S   0.0   0.0   0:00.81 bash
 5606 xbren     20   0   18920   2148   1528 R   0.0   0.0   0:00.04 top

输出的分上下两部分。第一部分显示的是系统的概况。第二部分显示了进程的实时概要信息。

第一部分的第一行显示了当前时间、系统的运行时间、登录的用户数以及系统的平均负载。平均负载有 3 个值:最近 1 分钟的、最近 5 分钟的和最近 15 分钟的平均负载。值越大说明系统的负载越高。由于进程短期的突发性活动,出现最近 1 分钟的高负载值也很常见,但如果近 15 分钟内的平均负载都很高,就说明系统可能有问题。

Linux 系统管理的要点在于定义究竟到什么程度才算是高负载。这个值取决于系统的硬件配置以及系统上通常运行的程序。对某个系统来说是高负载的值可能对另一系统来说就是正常值。在单核机器上,负载的意义是这样的,比如最近十五分钟的负载值为 5.09,含义为计算机的平均过载为 409%。平均而言,有 4.09 个进程在等待 CPU。通常对于单核机器来说,如果系统的负载值超过了 2,就说明系统比较繁忙了。但是对于多核机器来说,就不是这样计算的了。例如,如果在单 CPU 系统上的平均负载为 2,则意味着系统过载了 100%,在整个时间段内,一个进程正在使用 CPU,而另一个进程正在等待。在具有两个 CPU 的系统上,含义为两个不同的进程始终使用两个不同的 CPU。在具有四个 CPU 的系统上,这将代表只有 50%的使用率-两个进程使用两个 CPU,而两个 CPU 处于空闲状态。

第二行显示了进程概要信息——top 命令的输出中将进程叫作任务(task):有多少进程处在运行、休眠、停止或是僵化状态(僵化状态是指进程完成了,但父进程没有响应)。

下一行显示了 CPU 使用的概要信息。由前到后分别为:用户态使用率,内核态使用率,用做 nice 加权的进程分配的用户态 cpu 使用率,空闲的 cpu 使用率,等待磁盘写入完成时间比,硬件中断消耗时间,软件中断消耗时间,为处理其他进程而从虚拟机中偷走的 cpu 时间(仅虚拟机)。

紧跟其后的两行说明了系统内存的状态。第一行说的是系统的物理内存:总共有多少内存,还有多少空闲,当前用了多少,缓存占用了多少。后一行说的是同样的信息,不过是针对系统交换空间(如果分配了的话)的状态而言的。


第二部分显示了当前运行中的进程的详细列表,有些列跟 ps 命令的输出类似。给出一些未出现过的列的解释

默认情况下,top 命令在启动时会按照 %CPU 值对进程排序。可以在 top 运行时使用多种交互命令重新排序。每个交互式命令都是单字符,在 top 命令运行时键入可改变 top 的行为。键入 f 允许你选择对输出进行排序的字段,键入 d 允许你修改轮询间隔。键入 q 可以退出 top。用户在 top 命令的输出上有很大的控制权。用这个工具就能经常找出占用系统大部分资源的罪魁祸首。当然了,一旦找到,下一步就是结束这些进程。这也正是接下来的话题。

kill 发送信号

作为系统管理员,很重要的一个技能就是知道何时以及如何结束一个进程。有时进程挂起了,只需要动动手让进程重新运行或结束就行了。但有时,有的进程会耗尽 CPU 且不释放资源。在这两种情景下,你就需要能控制进程的命令。Linux 沿用了 Unix 进行进程间通信的方法。

在 Linux 中,进程之间通过信号来通信。进程的信号就是预定义好的一个消息,进程能识别它并决定忽略还是作出反应。进程如何处理信号是由开发人员通过编程来决定的。大多数编写完善的程序都能接收和处理标准 Unix 进程信号。这些信号列举如下。

信号名称描述
1HUP挂起
2INT中断
3QUIT结束运行
9KILL无条件终止
11SEGV段错误
15TERM尽可能终止
17STOP无条件停止运行,但不终止
18TSTP停止或暂停,但继续在后台运行
19CONT在 STOP 或 TSTP 之后恢复执行

在 Linux 上有两个命令可以向运行中的进程发出进程信号。

kill 命令可通过进程 ID(PID)给进程发信号。默认情况下,kill 命令会向命令行中列出的全部 PID 发送一个 TERM 信号。遗憾的是,你只能用进程的 PID 而不能用命令名,所以 kill 命令有时并不好用。要发送进程信号,你必须是进程的属主或登录为 root 用户。否则会提示Operation not permitted

TERM 信号告诉进程可能的话就停止运行。不过,如果有不服管教的进程,那它通常会忽略这个请求。如果需要强制终止,可以指定广为人知的-9 参数,即 KILL 信号。

同时,-s 参数支持指定其他信号(用信号名或信号值)。

$ kill -s HUP 3940

要检查 kill 命令是否有效,可再运行 ps 或 top 命令,看看问题进程是否已停止。

第二个是 killall 命令,它非常强大,它支持通过进程名而不是 PID 来结束进程。killall 命令也支持通配符,这在系统因负载过大而变得很慢时很有用。

$ killall http*

上例中的命令结束了所有以 http 开头的进程,比如 Apache Web 服务器的 httpd 服务。 以 root 用户身份登录系统时,使用 killall 命令要特别小心,因为很容易就会误用通配符而结束了重要的系统进程。这可能会破坏文件系统。

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »