zoukankan      html  css  js  c++  java
  • Linux Shell之监测程序

    监测程序

    一、探查进程

      当程序运行在系统上时,我们称之为进程(process)。想要监测这些进程,需要熟悉ps命令的用法。ps命令好比工具中的瑞士军刀,它能输出运行在系统上的所有程序的许多信息。

      但是随着ps命令的稳健而来的还有复杂性--有数不清的参数,这或许让ps命令成了最难掌握的命令。大多数系统管理员在掌握了能提供他们需要信息的一组参数后,就一直坚持只使用这组参数。

      默认情况下,ps命令并不会提供那么多的信息:

    1 xiaoyu@ubuntu:~$ ps
    2    PID TTY          TIME CMD
    3   2051 pts/18   00:00:00 bash
    4   2162 pts/18   00:00:00 ps
    5 xiaoyu@ubuntu:~$

      默认情况下,ps命令只会显示运行在当前控制台下的属于当前用户的进程,在此例中,我们只运行了bash shell(shell也只是运行在系统上的另一个程序而已)以及ps命令本身。

      上例中的基本输出显示了程序的进程ID(Process ID, PID)、它们运行在哪个终端(TTY)以及进程已用的CPU时间。

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

    •   Unix风格的参数,前面加单破折线;
    •   BSD风格的参数,前面不加破折线;
    •   GNU风格的长参数,前面加双破折线。

       1、Unix风格的参数  

      Unix风格的参数是从贝尔实验室开发的AT&T Unix系统上原有的ps命令继承下来的,这些参数如下表所示

    参数 m描述
    -A 
    显示所有进程
    -N
    显示与指定参数不符的所有进程
    -a 显示除控制进程(session leader)和无终端进程外的所有进程
    -d 显示除控制进程外的所有进程
    -e 显示所有进程
    -C cmdlist 显示包含在cmdlist列表中的进程
    -G grplist 显示组ID在grplist列表中的进程
    -U userlist 显示属主的用户ID在userlist列表中的进程
    -g grplist 显示会话或组ID在grplist列表中的进程
    -p pidlist 显示PID在pidlist列表中的进程
    -s sesslist 显示会话ID在sesslist列表中的进程
    -t ttylist 显示终端ID在ttylist列表中的进程
    -u userlist 显示有效用户ID在userlist列表中的进程
    -F 显示更多额外输出(相对-f参数而言)
     -O format  显示默认的输出列以及format列表指定的特定列
    -M  显示进程的安全信息
    -c  显示进程的额外调度器信息
    -f  显示完整格式的输出
    -j   显示任务信息
    -l   显示长列表
     -o format  仅显示由format指定的列
     -y  不要显示进程标记(process flag,表明进程状态的标记)
     -Z  显示安全标签(security context)①信息
     -H  用层级格式来显示进程(树状,用来显示父进程)
     -n namelist  定义了WCHAN列显示的值
     -w 采用宽输出模式,不限宽度显示
    -L   显示进程中的线程 
    -V  显示ps命令的版本号

     上面给出的参数已经很多了,不过还有很多。使用ps命令的关键不在于记住所有可用的参数,而在于记住最有用的那些参数。大多数Linux系统管理员都有自己的一组参数,他们会牢牢记住这些用来提取有用的进程信息的参数。举个例子,如果你想查看系统上运行的所有进程,可用-ef参数组合(ps命令允许你像这样把参数组合在一起)。

     1 xiaoyu@ubuntu:~$ ps -ef
     2 UID         PID   PPID  C STIME TTY          TIME CMD
     3 root          1      0  0 05:25 ?        00:00:02 /sbin/init auto noprompt
     4 root          2      0  0 05:25 ?        00:00:00 [kthreadd]
     5 root          4      2  0 05:25 ?        00:00:00 [kworker/0:0H]
     6 root          6      2  0 05:25 ?        00:00:00 [mm_percpu_wq]
     7 root          7      2  0 05:25 ?        00:00:00 [ksoftirqd/0]
     8 root          8      2  0 05:25 ?        00:00:00 [rcu_sched]
     9 root          9      2  0 05:25 ?        00:00:00 [rcu_bh]
    10 root         10      2  0 05:25 ?        00:00:00 [migration/0]
    11 root         11      2  0 05:25 ?        00:00:00 [watchdog/0]
    12 root         12      2  0 05:25 ?        00:00:00 [cpuhp/0]

       截取一段,Linux系统上运行着很多进程。这个例子用了两个参数:-e参数指定显示所有运行在系统上的进程;-f参数则扩展了输出,这些扩展的列包含了有用的信息。

    •   UID:启动这些进程的用户。
    •   PID:进程的进程ID。
    •   PPID:父进程的进程号(如果该进程是由另一个进程启动的)。
    •   C:进程生命周期中的CPU利用率。
    •   STIME:进程启动时的系统时间。
    •   TTY:进程启动时的终端设备。
    •   TIME:运行进程需要的累计CPU时间。
    •   CMD:启动的程序名称。

       上例子中输出了合理数量的信息,这也正是大多数系统管理员希望看到的。如果想要获得更多的信息,可采用-l参数,他会产生一个长格式输出。

    1 xiaoyu@ubuntu:~$ ps -l
    2 F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
    3 0 S  1000   2051   2045  0  80   0 -  7373 wait   pts/18   00:00:00 bash
    4 0 R  1000   2249   2051  0  80   0 -  8996 -      pts/18   00:00:00 ps
    5 xiaoyu@ubuntu:~$ 

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

    •   F:内核分配给进程的系统标记。
    •   S:进程的状态(O代表正在运行;S代表在休眠;R代表可运行,正等待运行;Z代表僵化--僵尸进程,进程已结束但父进程已不存在;T代表停止)。
    •   PRI:进程的优先级(越大的数字代表越低的优先级)。
    •   NI:谦让度值用来参与决定优先级。
    •   ADDR:进程的内存地址。
    •   SZ:假如进程被换出,所需交换空间的大致大小。
    •   WCHAN:进程休眠的内核函数的地址。

       2、BSD风格的参数

      了解了Unix风格的参数之后,我们来一起看一下BSD风格的参数。伯克利软件发行版(Berkeley software distribution,BSD)是加州大学伯克利分校开发的一个Unix版本。它和AT&TUnix系统有许多细小的不同,这也导致了多年的Unix争论。BSD版的ps命令参数如下表所示。
    参数 描述
    T 显示跟当前终端关联的所有进程
    a 显示跟任意终端关联的所有进程
    g 显示所有的进程,包括控制进程
    r 仅显示运行中的进程
    x 显示所有的进程,甚至包括未分配任何终端的进程
    U userlist 显示归userlist列表中某用户ID所有的进程
    p pidlist 显示PID在pidlist列表中的进程
    t ttylist 显示所关联的终端在ttylist列表中的进程
    O format 除了默认输出的列之外,还输出由format指定的列
    X 按过去的Linux i386寄存器格式显示
    Z 将安全信息添加到输出中
    j 显示任务信息
    l 采用长模式
    o format 仅显示由format指定的列
    s 采用信号格式显示
    u 采用基于用户的格式显示
    v 采用虚拟内存格式显示
    N namelist 定义在WCHAN列中使用的值
    O order 定义显示信息列的顺序
    S 将数值信息从子进程加到父进程上,比如CPU和内存的使用情况
    c 显示真实的命令名称(用以启动进程的程序名称)
    e 显示命令使用的环境变量
    f 用分层格式来显示进程,表明哪些进程启动了哪些进程
    h 不显示头信息
    k sort 指定用以将输出排序的列
    n 和WCHAN信息一起显示出来,用数值来表示用户ID和组ID 
    w 为较宽屏幕显示宽输出
    H 将线程按进程来显示
    m 在进程后显示线程
    L 列出所有格式指定符
    V  显示ps命令的版本号

      如你所见,Unix和BSD类型的参数有很多重叠的地方。使用其中某种类型参数得到的信息也同样可以使用另一种获得。大多数情况下,你只要选择自己所喜欢格式的参数类型就行了(比如你在使用Linux之前就已经习惯BSD环境了)。在使用BSD参数时,ps命令会自动改变输出以模仿BSD格式。下例是使用l参数的输出:

    1 xiaoyu@ubuntu:~$ ps l
    2 F   UID    PID   PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
    3 0  1000   2051   2045  20   0  29492  4936 wait   Ss   pts/18     0:00 bash
    4 0  1000   2354   2051  20   0  35984  1496 -      R+   pts/18     0:00 ps l
    5 xiaoyu@ubuntu:~$ 

      注意,其中大部分的输出列跟使用Unix风格参数时的输出是一样的,只有一小部分不同。

    •   VSZ:进程在内存中的大小,以千字节(KB)为单位。
    •   RSS:进程在未换出时占用的物理内存。
    •   STAT:代表当前进程状态的双字符状态码。

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

    •   <:该进程运行在高优先级上。
    •   N:该进程运行在低优先级上。
    •   L:该进程有页面锁定在内存中。
    •   s:该进程是控制进程。
    •   l:该进程是多线程的。
    •   +:该进程运行在前台。

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

       3、GNU长参数

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

    参数 描述
    --deselect 显示所有进程,命令行中列出的进程
    --Group grplist 显示组ID在grplist列表中的进程
    --User userlist 显示用户ID在userlist列表中的进程
    --group grplist 显示有效组ID在grplist列表中的进程
    --pid pidlist 显示PID在pidlist列表中的进程
    --ppid pidlist 显示父PID在pidlist列表中的进程
    --sid sidlist 显示会话ID在sidlist列表中的进程
    --tty ttylist 显示终端设备号在ttylist列表中的进程
    --user userlist 显示有效用户ID在userlist列表中的进程
    --format format 仅显示由format指定的列
    --context 显示额外的安全信息
    --cols n 将屏幕宽度设置为n列
    --columns n 将屏幕宽度设置为n列
    --cumulative 包含已停止的子进程的信息
    --forest 用层级结构显示出进程和父进程之间的关系
    --headers 在每页输出中都显示列的头
    --no-headers 不显示列的头
    --lines n 将屏幕高度设为n行
    --rows n 将屏幕高度设为n排
    --sort order 指定将输出按哪列排序
    --width n 将屏幕宽度设为n列
    --help 显示帮助信息
    --info 显示调试信息
    --version 示ps命令的版本号
      可以将GNU长参数和Unix或BSD风格的参数混用来定制输出。GNU长参数中一个着实让人喜爱的功能就是--forest参数。它会显示进程的层级信息,并用ASCII字符绘出可爱的图表。
    1 xiaoyu@ubuntu:~$ ps --forest
    2    PID TTY          TIME CMD
    3   2051 pts/18   00:00:00 bash
    4  43622 pts/18   00:00:00  \_ ps
    5 xiaoyu@ubuntu:~$

     二、实时监测进程

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

       而top命令刚好适用这种情况。top命令跟ps命令相似,能够显示进程信息,但它是实时显示的,下图是top命令运行时输出的截图

     

      输出的第一部分显示的是系统的概况:第一行显示了当前时间、系统的运行时间、登录的用户数以及系统的平均负载。
      平均负载有3个值:最近1分钟的、最近5分钟的和最近15分钟的平均负载。值越大说明系统的负载越高。由于进程短期的突发性活动,出现最近1分钟的高负载值也很常见,但如果近15分钟内的平均负载都很高,就说明系统可能有问题。 
      说明   Linux系统管理的要点在于定义究竟到什么程度才算是高负载。这个值取决于系统的硬件配置以及系统上通常运行的程序。对某个系统来说是高负载的值可能对另一系统来说就是正常值。通常,如果系统的负载值超过了2,就说明系统比较繁忙了。

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

       下一行显示了CPU的概要信息。top根据进程的属主(用户还是系统)和进程的状态(运行、空闲还是等待)将CPU利用率分成几类输出。

       紧跟其后的两行说明了系统内存的状态。第一行说的是系统的物理内存:总共有多少内存,当前用了多少,还有多少空闲。后一行说的是同样的信息,不过是针对系统交换空间(如果分配了的话)的状态而言的。
       最后一部分显示了当前运行中的进程的详细列表,有些列跟ps命令的输出类似。
    •   PID:进程的ID。
    •   USER:进程属主的名字。
    •   PR:进程的优先级。
    •   NI:进程的谦让度值。
    •   VIRT:进程占用的虚拟内存总量。
    •   RES:进程占用的物理内存总量。
    •   SHR:进程和其他进程共享的内存总量。
    •   S:进程的状态(D代表可中断的休眠状态,R代表在运行状态,S代表休眠状态,T代表跟踪状态或停止状态,Z代表僵化状态)。
    •   %CPU:进程使用的CPU时间比例。
    •   %MEM:进程使用的内存占可用内存的比例。
    •   TIME+:自进程启动到目前为止的CPU时间总量。
    •   COMMAND:进程所对应的命令行名称,也就是启动的程序名。
      默认情况下,top命令在启动时会按照%CPU值对进程排序。可以在top运行时使用多种交互命令重新排序。每个交互式命令都是单字符,在top命令运行时键入可改变top的行为。键入f允许你选择对输出进行排序的字段,键入d允许你修改轮询间隔。键入q可以退出top。用户在top命令的输出上有很大的控制权。用这个工具就能经常找出占用系统大部分资源的罪魁祸首。当然了,一旦找到,下一步就是结束这些进程。

     三、结束进程

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

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

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

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

      1、kill命令

      kill命令可通过进程ID(PID)给进程发信号。默认情况下,kill命令会向命令行中列出的全部PID发送一个TERM信号,遗憾的是,你只能用进程的PID而不能用命令名,所以kill命令有时并不好用。

      要发送进程信号,你必须是进程的属主或登陆为root用户。

    1 xiaoyu@ubuntu:~$ kill 6447
    2 bash: kill: (6447) - Operation not permitted
    3 xiaoyu@ubuntu:~$ 

       TERM信号告诉进程可能的话就停止运行。不过,如果有不服管教的进程,那它通常会忽略这个请求。如果要强制终止,-s参数支持制定其他信号(用信号名或信号值)。

      从下例中看出,kill命令不会有任何输出。

    1 xiaoyu@ubuntu:~$ kill 2120
    2 xiaoyu@ubuntu:~$ 

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

      2、killall命令

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

    1 xiaoyu@ubuntu:~$ killall http*
    2 http*: no process found
    3 xiaoyu@ubuntu:~$ 

       嗯,我这台机器没有启动任何http的进程,不过这个命令大家是可以尝试使用的

      警告   以root用户身份登录系统时,使用killall命令要特别小心,因为很容易就会误用通配符而结束了重要的系统进程。这可能会破坏文件系统。
  • 相关阅读:
    Pandas 学习记录(一)
    python 列表常用操作
    pandas 基本操作
    Numpy np.array 相关常用操作学习笔记
    JS控制背景音乐 没有界面
    Linux Awk使用案例总结
    Yii2 定时任务创建(Console 任务)
    YII2项目常用技能知识总结
    /etc/fstab readyonly 解决办法
    Redis 排行榜 自己简单练习
  • 原文地址:https://www.cnblogs.com/Reverse-xiaoyu/p/12070813.html
Copyright © 2011-2022 走看看