CentOS 7上的進程管理


一些雜亂的基礎概念

程序是一種靜態的文件,躺在磁盤上。而進程則是將程序運行起來放置於內存中。因此進程就是運行中的程序,是程序運行起來的一個實例。同一個程序可以運行為多個進程/實例。

進程之間有父子關系,即父進程與子進程之間的關系。父進程結束后,子進程也會隨之結束。因此,當我們通過終端連接上之后,隨即啟用了一個與終端相關的shell進程(如bash),我們在該終端中運行的任何程序,都是這個終端的子進程。因此當我們在終端中運行一個需要長時間執行的程序,還未運行完畢便退出終端的話,那么該長時間運行的程序也會自動結束掉的。

進程一般通過一些系統調用來創建,例如進程通過fork()或者clone()來復制自身創建新進程。

CentOS 6上最上層的進程是init進程,CentOS 7上最上層的進程是systemd進程。在一些情況下,父進程結束后,子進程還會存在,這類子進程被稱為孤兒進程(orphan process),它們會被init/systemd進程所“收養”。

進程有優先級的概念,優先級越低的進程可以享受越多的CPU資源。無法直接調整進程的優先級,只能通過調整進程的nice值來改變,nice值越高進程優先級越高(優先級高越不優先)。可以理解為越高的nice值表示進程更願意占用更少的CPU資源。普通用戶只可以調高自身進程的nice值,只有root用戶才可以隨意調整nice值。

關於內存的一些基本概念,例如物理內存、虛擬內存、內存分頁和多級分頁表,推薦閱讀【Linux的內存分頁管理 - Vamei - 博客園】

進程間通信

  • 主機內部。
    • signal(信號)。
    • shm(SHared Memory,共享內存)。
    • semaphore(信號量)。
  • 主機之間。
    • RPC(Remote Procedure Call,遠程過程調用)。
    • socket。

進程類型

守護進程(daemon):一般是作為服務類的進程運行於系統后台,與終端無關。一般是隨系統啟動的時候啟動,也可以在系統啟動后在終端手動啟動,啟動后會自動進入系統后台。例如常見的httpd、nginx和mysqld等服務。

前台進程:運行與前台的進程,與終端相關,如果需要一段運行時間的話,會占用終端。例如我們基於php-cli工具手工運行一些php腳本。

進程根據占用資源的類型還可以分為CPU密集型(CPU-Bound)和IO密集型(IO-Bound)。

進程狀態

  • 運行態:running。
  • 就緒態:ready。
  • 睡眠態:分為兩種,可中斷(interruptable)睡眠和不可中斷(uninterruptable)睡眠。不可中斷的睡眠一般是由於進程在等待IO處理。
  • 停止態:stopped,處於內存中停止的狀態,不會占用CPU資源,除非手動啟動。
  • 僵死態:zombie,類似進程卡死吧,是一種不好的狀態。

init進程

在Linux系統中,操作系統在啟動過程中如何一步步啟動進程,系統如何管理進程與服務,這些都與一個初始化進程相關,那就是init進程。它一般是OS中最先啟動的進程,一般PID為0。在不同的CentOS版本中其對應的init進程不一樣。

目前大多數主流的Linux發行版采用Systemd方案。

 

 

命令

pstree

pstree用於以樹狀的形式顯示當前的進程。

[root@C7 ~]# pstree
systemd─┬─ModemManager───2*[{ModemManager}]
        ├─NetworkManager─┬─dhclient
        │                └─2*[{NetworkManager}]
        ├─VGAuthService
        ├─2*[abrt-watch-log]
        ├─abrtd
        ├─accounts-daemon───2*[{accounts-daemon}]
        ├─alsactl
        ├─at-spi-bus-laun─┬─dbus-daemon
        │                 └─3*[{at-spi-bus-laun}]
        ├─at-spi2-registr───2*[{at-spi2-registr}]
        ├─atd
        ├─auditd─┬─audispd─┬─sedispatch
        │        │         └─{audispd}
        │        └─{auditd}
        ├─avahi-daemon───avahi-daemon
        ├─bluetoothd
        ├─colord───2*[{colord}]
        ├─crond
        ├─cupsd
        ├─2*[dbus-daemon]
        ├─dbus-launch
        ├─dnsmasq───dnsmasq
        ├─firewalld───{firewalld}
        ├─gdm─┬─X───5*[{X}]
        │     ├─gdm-session-wor─┬─gnome-session-b─┬─gnome-shell─┬─ibus-daemon─┬─ibus-dconf───3*[{ibus-dconf}]
        │     │                 │                 │             │             ├─ibus-engine-sim───2*[{ibus-engine-sim}]
        │     │                 │                 │             │             └─2*[{ibus-daemon}]
        │     │                 │                 │             └─20*[{gnome-shell}]
        │     │                 │                 ├─gsd-a11y-keyboa───3*[{gsd-a11y-keyboa}]
        │     │                 │                 ├─gsd-a11y-settin───3*[{gsd-a11y-settin}]
        │     │                 │                 ├─gsd-clipboard───2*[{gsd-clipboard}]
        │     │                 │                 ├─gsd-color───3*[{gsd-color}]
        │     │                 │                 ├─gsd-datetime───2*[{gsd-datetime}]
        │     │                 │                 ├─gsd-housekeepin───2*[{gsd-housekeepin}]
        │     │                 │                 ├─gsd-keyboard───3*[{gsd-keyboard}]
        │     │                 │                 ├─gsd-media-keys───3*[{gsd-media-keys}]
        │     │                 │                 ├─gsd-mouse───2*[{gsd-mouse}]
        │     │                 │                 ├─gsd-power───3*[{gsd-power}]
        │     │                 │                 ├─gsd-print-notif───2*[{gsd-print-notif}]
        │     │                 │                 ├─gsd-rfkill───2*[{gsd-rfkill}]
        │     │                 │                 ├─gsd-screensaver───2*[{gsd-screensaver}]
        │     │                 │                 ├─gsd-sharing───3*[{gsd-sharing}]
        │     │                 │                 ├─gsd-smartcard───4*[{gsd-smartcard}]
        │     │                 │                 ├─gsd-sound───3*[{gsd-sound}]
        │     │                 │                 ├─gsd-wacom───2*[{gsd-wacom}]
        │     │                 │                 ├─gsd-xsettings───3*[{gsd-xsettings}]
        │     │                 │                 └─3*[{gnome-session-b}]
        │     │                 └─2*[{gdm-session-wor}]
        │     └─3*[{gdm}]
        ├─gssproxy───5*[{gssproxy}]
        ├─ibus-portal───2*[{ibus-portal}]
        ├─ibus-x11───2*[{ibus-x11}]
        ├─irqbalance
        ├─ksmtuned───sleep
        ├─libvirtd───16*[{libvirtd}]
        ├─lsmd
        ├─lvmetad
        ├─master─┬─pickup
        │        └─qmgr
        ├─packagekitd───2*[{packagekitd}]
        ├─polkitd───5*[{polkitd}]
        ├─pulseaudio───2*[{pulseaudio}]
        ├─rngd
        ├─rpcbind
        ├─rsyslogd───2*[{rsyslogd}]
        ├─rtkit-daemon───2*[{rtkit-daemon}]
        ├─smartd
        ├─sshd─┬─sshd───bash───man───less
        │      └─sshd───bash───pstree
        ├─systemd-journal
        ├─systemd-logind
        ├─systemd-udevd
        ├─tuned───4*[{tuned}]
        ├─udisksd───4*[{udisksd}]
        ├─upowerd───2*[{upowerd}]
        ├─vmtoolsd───{vmtoolsd}
        ├─wpa_supplicant
        └─xdg-permission-───2*[{xdg-permission-}]

對於相同的子進程,pstree會將其折疊,並使用數字顯示其相同子進程數。例如。

init-+-getty
      |-getty
      |-getty
      `-getty

會被折疊成。

init---4*[getty]

子進程的折疊顯示使用的是方括號,而子線程的折疊顯示使用了方括號與花括號。

icecast2---13*[{icecast2}]

-c:如果想要取消折疊(compact)功能的話,可使用該選項。

-p:默認情況下,pstree不會顯示PID,加上該選項可實現顯示PID功能。該選項暗含了-c選項(禁用折疊)。

知道了PID之后,pstree可加上PID參數,用來顯示以某個PID為根的進程樹。

[root@C7 ~]# pstree -p 1214
tuned(1214)─┬─{tuned}(1541)
            ├─{tuned}(1542)
            ├─{tuned}(1543)
            └─{tuned}(1558)

-a:顯示進程的命令行選項參數等。使用該選項有時會因為命令行參數太長而無法顯全,可結合-l選項查看長格式。

  ├─dbus-daemon --fork --print-pid 5 --print-address 7 --session
  ├─dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation

-h:高亮顯示當前進程以及祖先進程。

-H:高亮顯示指定PID進程以及祖先進程。

# pstree -H PID

-g:顯示進程的PGID(Process Group ID,進程組ID),我不懂什么是進程組,從結果來看,子進程和進程的子線程的PGID等同於父進程的PID。同時顯示PID和PGID時,先顯示PID后顯示PGID。

-s:顯示進程的祖先進程。

[root@C7 ~]# pstree -p 1541
{tuned}(1541)
[root@C7 ~]# pstree -sp 1541
systemd(1)───tuned(1214)───{tuned}(1541)

-u:顯示進程的用戶名(UID),如果有的話。知道用戶名以后,用戶名可作為命令參數來顯示與該用戶名相關的進程樹。

[root@C7 ~]# pstree -p postfix
pickup(3311)

qmgr(1401)

 

ps

ps命令用於顯示當前系統上的進程信息,也叫做當前進程快照(snapshot)。

它支持三種風格的選項:

  • UNIX風格,選項可以被合並並且只能有一個連接號(-)。在man手冊中,UNIX風格,也叫做標准(standard)或者POSIX風格。
  • BSD風格,選項可以被合並並且不能有連接號(-)。
  • GNU長選項,必須有兩個連接號(-)。

由於ps有許多不同的版本,因此該版本(CentOS 7上的ps)為了兼容性考慮,會存在許多功能相同的選項。不同風格的選項可以混合使用,但是可能會產生沖突,因此建議不要混合使用。

不同風格的選項名稱(字符)可能相同但不代表含義相同,例如以下2個命令,意義就不一樣。

# ps aux
# ps -aux

雖然它們顯示的結果是相同的,下文會解釋。

選項組合一:aux

a:使ps列出所有和終端(tty)相關的進程,當和x選項共同使用的時候顯示所有的進程。

x:使ps列出所有和你(應該是當前的有效UID,Effective UID)相關的進程,當和x選項共同使用的時候顯示所有的進程。

u:以面向用戶的格式輸出。

a和x選項屬於簡單進程選取(SIMPLE PROCESS SELECTION)類選項。

u選項屬於輸出格式控制(OUTPUT FORMAT CONTROL)類選項。

因此該組合的作用是:以面向用戶的格式,BSD的風格顯示系統上所有的進程信息。

[root@C7 ~]# ps aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.2  0.4 191172  4168 ?        Ss   10:03   0:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root          2  0.0  0.0      0     0 ?        S    10:03   0:00 [kthreadd]
root          3  0.0  0.0      0     0 ?        S    10:03   0:00 [ksoftirqd/0]
root          5  0.0  0.0      0     0 ?        S<   10:03   0:00 [kworker/0:0H]
...
root        499  0.0  0.3  37376  3496 ?        Ss   10:03   0:00 /usr/lib/systemd/systemd-journald
root        528  0.0  0.1 124792  1320 ?        Ss   10:03   0:00 /usr/sbin/lvmetad -f
root        532  0.0  0.3  45648  3032 ?        Ss   10:03   0:00 /usr/lib/systemd/systemd-udevd
...
root       1495  0.0  1.8 320832 18444 tty1     Ssl+ 10:03   0:00 /usr/bin/X :0 -background none -noreset -audit 4 -verbose -auth /run/gdm/auth-for-gdm-lKoaJ3/database -seat seat0 -nolist
...
root       1949  0.0  0.3 116628  3256 pts/0    Ss   10:04   0:00 -bash
root       1990  0.0  0.2 119788  2472 pts/0    S+   10:05   0:00 man ps
root       2003  0.0  0.0 110336   980 pts/0    S+   10:05   0:00 less -s
...

我們再來看一下ps -aux的含義。

-a:選取除了會話首進程(session leader,相見getsid(2)的man手冊)和與終端無關的進程以外的所有進程。

-u:根據有效用戶ID(EUID)來選取進程。其后接的就是用戶名了。

因此,“-aux”的含義即選取滿足用戶名為“x”和-a選項條件的進程,如果不存在用戶x,那么其效果等同於“aux”,這也就是為什么在實際運行時,“ps aux”和“ps -aux”的結果是一樣的了。

接下來解釋幾個字段的含義。

USER:進程所對應的用戶。

PID:進程ID。

%CPU:進程所占用的CPU百分比,占用的CPU時間/進程所運行的時間(cputime/realtime)。

%MEM:進程所占用的內存百分比。

VSZ:虛擬內存的大小,單位是KB。設備映射當前不包含;這點可能會改變。

RSS:Resident Size,常駐內存集,單位是KB。一個任務所使用到的非swap物理內存。

TTY:與進程所關聯的終端。

STAT:進程狀態。默認情況下,似乎進程的狀態只有在BSD風格的選項下才會被顯示。在UNIX風格的話,可能得通過-o來顯示了,並且使用了-o,就不可以使用其他UNIX風格的輸出格式控制了,例如-o和-f一起用是不行的。

  • R:running,運行態。
  • S:Interruptable Sleeping,可中斷睡眠態。
  • D:Uninterruptable Sleeping,不可中斷睡眠態。進程處於等待的時候,可以理解為睡眠,如果進程是等待網絡或者磁盤的IO,這種一般是必須等待完畢才可以繼續運行進程的,那么這種是不可中斷的睡眠狀態,反之則為可中斷。
  • T:Stopped,停止態。進程通過Ctrl+z調入后台時處於該狀態。
  • Z:Zombie,僵死態。進程等待被回收。
  • +:前台進程。
  • l:多線程進程。
  • N:低優先級進程。具備nice值,對其他進程nice,因此這里說的”優先級“就真的是越低越不優先了。
  • <:高優先級進程。
  • s:session leader,會話首進程。

START:進程所啟動的時間點。

TIME:進程所占用的CPU時間。

COMMAND:完整的命令行信息。

選項組合二:-ef

-e:選擇所有的進程,等同於-A。

-f:顯示長格式詳細信息。

[root@C7 ~]# ps -ef 
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 10:03 ?        00:00:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root          2      0  0 10:03 ?        00:00:00 [kthreadd]
root          3      2  0 10:03 ?        00:00:00 [ksoftirqd/0]
root          5      2  0 10:03 ?        00:00:00 [kworker/0:0H]
...
root        691      1  0 10:03 ?        00:00:00 /sbin/auditd
root        693    691  0 10:03 ?        00:00:00 /sbin/audispd
root        695    693  0 10:03 ?        00:00:00 /usr/sbin/sedispatch
...
root       1495   1231  0 10:03 tty1     00:00:00 /usr/bin/X :0 -background none -noreset -audit 4 -verbose -auth /run/gdm/auth-for-gdm-lKoaJ3/database -seat seat0 -nolisten tcp vt1
...
root       1949   1943  0 10:04 pts/0    00:00:00 -bash
root       1990   1949  0 10:05 pts/0    00:00:00 man ps
root       2003   1990  0 10:05 pts/0    00:00:00 less -s
root       2017   1213  0 10:06 ?        00:00:00 sshd: root@pts/1
root       2023   2017  0 10:06 pts/1    00:00:00 -bash
...

UID:等同於ps aux輸出中的USER,進程的用戶。

PPID:該進程的父進程ID。

C:CPU的使用情況,等同於%CPU。

CMD:等同於COMMAND。

-f選項還可以結合其他的UNIX風格選項來增加額外的字段信息。例如結合-L選項。

-L:顯示線程信息,NLWP表示線程數量,LWP表示線程ID。LWP的英文全稱是Light Weight Process,由此可見,線程即是輕量級的進程。

[root@C7 ~]# ps -efL | head -n 1
UID         PID   PPID    LWP  C NLWP STIME TTY          TIME CMD
[root@C7 ~]# ps -ef | grep "auditd"
root        109      2  0 10:03 ?        00:00:00 [kauditd]
root 691 1 0 10:03 ? 00:00:00 /sbin/auditd
root       6178   2023  0 15:41 pts/1    00:00:00 grep --color=auto auditd
[root@C7 ~]# ps -efL | grep "auditd"
root        109      2    109  0    1 10:03 ?        00:00:00 [kauditd]
root 691 1 691 0 2 10:03 ? 00:00:00 /sbin/auditd root 691 1 692 0 2 10:03 ? 00:00:00 /sbin/auditd
root       6180   2023   6180  0    1 15:41 pts/1    00:00:00 grep --color=auto auditd

可見,原本/sbin/auditd只是一條進程信息,在顯示線程信息后,它顯示成了2條,PID相同,不過線程ID(LWP)不同。

選項組合三:-eFH

-F:基於-f選項,顯示比起更詳細的信息。

-H:以進程樹的格式顯示。

[root@C7 ~]# ps -eFH
UID         PID   PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
root          2      0  0     0     0   0 10:03 ?        00:00:00 [kthreadd]
root          3      2  0     0     0   0 10:03 ?        00:00:00   [ksoftirqd/0]
root          5      2  0     0     0   0 10:03 ?        00:00:00   [kworker/0:0H]
root          7      2  0     0     0   0 10:03 ?        00:00:00   [migration/0]
root          8      2  0     0     0   0 10:03 ?        00:00:00   [rcu_bh]
...
root          1      0  0 47793  4168   1 10:03 ?        00:00:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root        499      1  0  9344  4028   0 10:03 ?        00:00:00   /usr/lib/systemd/systemd-journald
root        528      1  0 31198  1320   2 10:03 ?        00:00:00   /usr/sbin/lvmetad -f
root        532      1  0 11412  3032   1 10:03 ?        00:00:00   /usr/lib/systemd/systemd-udevd
root        691      1  0 13877   900   2 10:03 ?        00:00:00   /sbin/auditd
root        693    691  0 21138   936   0 10:03 ?        00:00:00     /sbin/audispd
root        695    693  0 13899  1416   0 10:03 ?        00:00:00       /usr/sbin/sedispatch
...

SZ:進程的core image的物理頁(page)大小。包含文本、數據和棧空間(stack space)。設備映射當前不包含;這點可能會改變。

PSR:進程目前在哪個CPU核心上運行。

選項組合四:-eo,axo

o, -o, --format:輸出格式的一種格式,可以讓用戶自定義顯示字段信息。字段信息是一個列表,以逗號或者空格分隔,一般以逗號。字段信息使用關鍵詞(keyword)來表示,關鍵詞除了可用於-o選項顯示字段信息外,還可用於--sort選項來分類排序。例如。

[root@C7 ~]# ps -eo pid,user,args --sort user | head
   PID USER     COMMAND
   731 avahi    avahi-daemon: running [C7.local]
   746 avahi    avahi-daemon: chroot helper
  1726 colord   /usr/libexec/colord
   744 dbus     /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
  1512 gdm      /usr/libexec/gnome-session-binary --autostart /usr/share/gdm/greeter/autostart
  1518 gdm      dbus-launch --exit-with-session /usr/libexec/gnome-session-binary --autostart /usr/share/gdm/greeter/autostart
  1519 gdm      /usr/bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
  1526 gdm      /usr/libexec/at-spi-bus-launcher
  1531 gdm      /bin/dbus-daemon --config-file=/usr/share/defaults/at-spi2/accessibility.conf --nofork --print-address 3

字段名也可以置空或者根據需求重命名。如果全部置空的話,就不會顯示首行字段名行了。

[root@C7 ~]# ps -eo pid,user=,args=mingling --sort user | head -n 3
   PID          mingling
   731 avahi    avahi-daemon: running [C7.local]
   746 avahi    avahi-daemon: chroot helper

字段的寬度會自動調節,也可以在字段名后面使用“:number”的形式來明確具體的寬度。

[root@C7 ~]# ps -eo uid:5,pid:10,ppid:30
  UID        PID                           PPID
    0          1                              0
    0          2                              0
    0          3                              2
    0          5                              2
    0          7                              2
    0          8                              2
...

當選項使用情況比較復雜的時候,可以使用多個-o選項。

具體的字段關鍵詞,在ps(1)的man手冊中的STANDARD FORMAT SPECIFIERS中有描述。

       CODE        HEADER    DESCRIPTION

       %cpu        %CPU      cpu utilization of the process in "##.#" format.  Currently, it is the CPU time used divided by the
                             time the process has been running (cputime/realtime ratio), expressed as a percentage.  It will not
                             add up to 100% unless you are lucky.  (alias pcpu).

       %mem        %MEM      ratio of the process's resident set size  to the physical memory on the machine, expressed as a
                             percentage.  (alias pmem).
... ...

CODE:在CLI中需要輸入的關鍵詞。

HEADER:在輸出中顯示的首行字段名稱。

DESCRIPTION:詳細的描述信息。

此前選項的輸出信息,如果某些字段不明了,也是參考這部分的信息。

基於列表選取進程

上面所述的選項,在選取進程的時候,都是選擇某一類進程。例如-e、ax選項可選取所有進程等等。

除此之外還可基於列表,列表可以是用戶列表或者PID列表。

先來看基於用戶列表。

以不同的格式顯示有效UID和真實UID為postfix的進程。

-u:有效(effective)UID,即EUID。EUID用於文件訪問權限的判斷。

-U:真實(real)UID,即RUID。RUID用戶識別創建進程的用戶。

[root@C7 ~]# ps -u postfix -U postfix -f
UID         PID   PPID  C STIME TTY          TIME CMD
postfix    1378   1374  0 11:04 ?        00:00:00 qmgr -l -t unix -u
postfix    3325   1374  0 12:44 ?        00:00:00 pickup -l -t unix -u
[root@C7 ~]# ps -u postfix -U postfix -F
UID         PID   PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
postfix    1378   1374  0 22968  4096   3 11:04 ?        00:00:00 qmgr -l -t unix -u
postfix    3325   1374  0 22951  4088   0 12:44 ?        00:00:00 pickup -l -t unix -u
[root@C7 ~]# ps -u postfix -U postfix u
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
postfix    1378  0.0  0.4  91872  4096 ?        S    11:04   0:00 qmgr -l -t unix -u
postfix    3325  0.0  0.4  91804  4088 ?        S    12:44   0:00 pickup -l -t unix -u

在這個示例中,我們也看到了不同風格選項的使用。並且為了避免ps程序感到疑惑,我們將選項分開書寫,向下面這個例子,就是寫在一起報錯了。

[root@C7 ~]# ps -uU postfix -F
error: user name does not exist

既然說是列表了,那么用戶名也可以多個。

[root@C7 ~]# ps -u postfix,colord,rtkit -f
UID         PID   PPID  C STIME TTY          TIME CMD
rtkit       732      1  0 11:04 ?        00:00:00 /usr/libexec/rtkit-daemon
postfix    1378   1374  0 11:04 ?        00:00:00 qmgr -l -t unix -u
colord     1727      1  0 11:04 ?        00:00:00 /usr/libexec/colord
postfix    3325   1374  0 12:44 ?        00:00:00 pickup -l -t unix -u

再來看進程列表。

p PID_LIST
-p PID_LIST
--pid PID_LIST
--ppid PID_LIST
[root@C7 ~]# ps -p 732,1378,1727,3325 -f
UID         PID   PPID  C STIME TTY          TIME CMD
rtkit       732      1  0 11:04 ?        00:00:00 /usr/libexec/rtkit-daemon
postfix    1378   1374  0 11:04 ?        00:00:00 qmgr -l -t unix -u
colord     1727      1  0 11:04 ?        00:00:00 /usr/libexec/colord
postfix    3325   1374  0 12:44 ?        00:00:00 pickup -l -t unix -u

進程列表也可以只有一個PID,此情況下可以直接作為ps命令的參數。

# ps PID
# ps -PID

這種適合於引用可返回PID的命令結果,例如pgrep。

[root@C7 ~]# ps -p $(pgrep systemd)
   PID TTY      STAT   TIME COMMAND
     1 ?        Ss     0:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
   498 ?        Ss     0:00 /usr/lib/systemd/systemd-journald
   534 ?        Ss     0:00 /usr/lib/systemd/systemd-udevd
   744 ?        Ss     0:00 /usr/lib/systemd/systemd-logind

也可以通過-C選項來實現同樣的功能。

-C cmdlist:根據命令名稱列表來匹配進程。

[root@C7 ~]# ps -C systemd,systemd-journald,systemd-udevd,systemd-logind -f
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 11:04 ?        00:00:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root        498      1  0 11:04 ?        00:00:00 /usr/lib/systemd/systemd-journald
root        534      1  0 11:04 ?        00:00:00 /usr/lib/systemd/systemd-udevd
root        744      1  0 11:04 ?        00:00:00 /usr/lib/systemd/systemd-logind

這里的列表,既不支持glob,也不支持RE。而且它是精確匹配。

[root@C7 ~]# ps -C "systemd*"
   PID TTY          TIME CMD
[root@C7 ~]# ps -C "systemd.*"
   PID TTY          TIME CMD
[root@C7 ~]# ps -C "system"
   PID TTY          TIME CMD

 

pgrep, pkill

pgrep基於pattern或者其他屬性查找進程,默認會輸出其PID。

pkill基於pattern或者其他屬性向進程發送信號(默認是SIGTERM),不會輸出進程信息。

# pgrep [options] pattern
# pkill [options] pattern

大部分選項是pgrep和pkill共用的,如果有專用,會單獨說明。

pgrep

為了做測試,我們安裝了一個apache httpd的服務。

# yum -y install httpd
# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: active (running) since Thu 2019-07-11 15:32:51 CST; 28min ago
     Docs: man:httpd(8)
           man:apachectl(8)
 Main PID: 5632 (httpd)
   Status: "Total requests: 10; Current requests/sec: 0; Current traffic:   0 B/sec"
    Tasks: 9
   CGroup: /system.slice/httpd.service
           ├─5632 /usr/sbin/httpd -DFOREGROUND
           ├─5643 /usr/sbin/httpd -DFOREGROUND
           ├─5644 /usr/sbin/httpd -DFOREGROUND
           ├─5645 /usr/sbin/httpd -DFOREGROUND
           ├─5646 /usr/sbin/httpd -DFOREGROUND
           ├─5648 /usr/sbin/httpd -DFOREGROUND
           ├─5754 /usr/sbin/httpd -DFOREGROUND
           ├─5755 /usr/sbin/httpd -DFOREGROUND
           └─5756 /usr/sbin/httpd -DFOREGROUND

Jul 11 15:31:29 C7 systemd[1]: Starting The Apache HTTP Server...
Jul 11 15:32:12 C7 httpd[5632]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::7ebe:48aa:260c:1099. Set the 'ServerName... this message
Jul 11 15:32:51 C7 systemd[1]: Started The Apache HTTP Server.
Hint: Some lines were ellipsized, use -l to show in full.

這里的pattern,是基於程序文件名稱來匹配的。

COMMAND
/usr/sbin/httpd -DFOREGROUND

就是上面紅色粗體字部分,其余部分不是用來和pattern進行匹配的。如果你匹配“sbin”或者“FORE”,那么是無法匹配出來的。

匹配是模糊匹配,“httpd”可被“http”所匹配。

默認返回pattern的PID。

[root@C7 ~]# pgrep httpd
5632
5643
5644
5645
5646
5648
5754
5755
5756

可通過命令結果引用顯示對應的進程信息。

[root@C7 ~]# ps $(pgrep httpd)
   PID TTY      STAT   TIME COMMAND
  5632 ?        Ss     0:00 /usr/sbin/httpd -DFOREGROUND
  5643 ?        S      0:00 /usr/sbin/httpd -DFOREGROUND
  5644 ?        S      0:00 /usr/sbin/httpd -DFOREGROUND
  5645 ?        S      0:00 /usr/sbin/httpd -DFOREGROUND
  5646 ?        S      0:00 /usr/sbin/httpd -DFOREGROUND
  5648 ?        S      0:00 /usr/sbin/httpd -DFOREGROUND
  5754 ?        S      0:00 /usr/sbin/httpd -DFOREGROUND
  5755 ?        S      0:00 /usr/sbin/httpd -DFOREGROUND
  5756 ?        S      0:00 /usr/sbin/httpd -DFOREGROUND

-c, --count:返回匹配pattern的進程統計計數,沒匹配到就返回0。

[root@C7 ~]# pgrep -c httpd
9
[root@C7 ~]# pgrep -c redis
0

-f, --full:上面我們說了,pattern的匹配,是僅根據程序文件名稱,不包括程序的路徑、命令選項、命令參數等。而啟用該選項的話,就可以對整個完整的進程信息進行匹配了。

[root@C7 ~]# pgrep -c GROUND
0
[root@C7 ~]# pgrep -cf GROUND
9
[root@C7 ~]# pgrep -c sbin
0
[root@C7 ~]# pgrep -cf sbin
35

-l, --list-name:默認情況下只顯示PID,使用該選項還可顯示進程名稱。不過僅僅只是進程名稱而已,一般使用-a選項來代替它。

-a, --list-full:顯示PID和完整的命令行信息。-l和-a都是僅適用於pgrep。

[root@C7 ~]# pgrep -a httpd
2129 /usr/sbin/httpd -DFOREGROUND
2148 /usr/sbin/httpd -DFOREGROUND
2149 /usr/sbin/httpd -DFOREGROUND
2150 /usr/sbin/httpd -DFOREGROUND
2152 /usr/sbin/httpd -DFOREGROUND
2153 /usr/sbin/httpd -DFOREGROUND

-P, --parent ppid,...:根據父進程ID來過濾。

[root@C7 ~]# pgrep -a -P 2129
2148 /usr/sbin/httpd -DFOREGROUND
2149 /usr/sbin/httpd -DFOREGROUND
2150 /usr/sbin/httpd -DFOREGROUND
2152 /usr/sbin/httpd -DFOREGROUND
2153 /usr/sbin/httpd -DFOREGROUND

-u, --euid euid,...:根據用戶名或者UID來過濾進程。

[root@C7 ~]# pgrep -a -u apache
2148 /usr/sbin/httpd -DFOREGROUND
2149 /usr/sbin/httpd -DFOREGROUND
2150 /usr/sbin/httpd -DFOREGROUND
2152 /usr/sbin/httpd -DFOREGROUND
2153 /usr/sbin/httpd -DFOREGROUND

顯示屬主為root的sshd進程。

[root@C7 ~]# pgrep -u root sshd

顯示屬主為postfix或者nobody的進程。

[root@C7 ~]# pgrep -u postfix,nobody

-v, --inverse:反向匹配,等同於“grep -v”。不過該選項的意義並不大,尤其是在使用pkill的時候,容易誤kill進程。因此pkill情況下只能使用長選項--inverse。不過還是建議不使用該選項,尤其是pkill。

-x, --exact:精確匹配。默認是上面說的模糊匹配。例如這個進程。

# /usr/bin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper

默認情況下,“dns”或者“masq”都可以匹配到。使用該選項后,必須使用“dnsmasq”。

如果搭配-f選項的話,那么必須使用“/usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper”才可以匹配成功。

pgrep一般用於命令結果引用,結合其他命令一起使用。

顯示所有xterm進程的信息。
$ ps -fp $(pgrep -d, -x xterm)
調整所有netscape進程的nice值。
$ renice +4 $(pgrep netscape)

pkill

向某類進程發送信號。默認發送的是SIGTERM信號,因此這里終止了所有的httpd進程。

[root@C7 ~]# pkill httpd

我本人不太建議使用pkill來終止服務類的進程,因為這么做,會造成這類進程的狀態異常。

即便在再次啟動服務后,也會有異常。

應該使用systemd來管理服務類進程。

可指定其他信號。

# pkill -SIG ...
# pkill --signal SIG ...

關於信號,在kill命令中會介紹。

 

pidof

返回進程的PID。

pidof [-s] [-c] [-n] [-x] [-m] [-o omitpid[,omitpid..]]  [-o omitpid[,omitpid..]..]  program [program..]

program,一般是命令的名稱或者完整路徑,不可帶命令的選項。

[root@C7 ~]# ps -f 760
UID         PID   PPID  C STIME TTY      STAT   TIME CMD
root        760      1  0 09:38 ?        Ss     0:01 /sbin/rngd -f
[root@C7 ~]# pidof rngd
760
[root@C7 ~]# pidof /sbin/rngd
760
[root@C7 ~]# pidof /sbin/rngd -f
pidof: invalid options on command line!

[root@C7 ~]# pidof "/sbin/rngd -f"
[root@C7 ~]#

當進程有多個PID的時候,返回多個,以空格作為分隔符。

[root@C7 ~]# pidof httpd
2237 2236 2235 2234 2233 2211

我看了pidof的其他選項,有點懵逼,並且我感覺這個命令的作用不是很大,和pgrep的功能似乎是一樣的。

pidof和killall5是同一個程序。后者用於向除了線程和自身會話的進程以外的所有進程發送信號。

[root@C7 ~]# ls -l /usr/sbin/pidof 
lrwxrwxrwx. 1 root root 18 Sep 27  2018 /usr/sbin/pidof -> /usr/sbin/killall5

 

top

ps命令,以快照的形式顯示系統當前進程信息。如果想要以動態的形式顯示進程信息的話,則可以使用top命令。

直接鍵入top回車后,如圖顯示。

默認情況下,是每隔3秒變化一次,最上面的部分是一些匯總信息,中間空行是用於用戶鍵入,下面的剩余部分是進程信息,進程信息默認以PID字段升序排序。

在該界面下,可通過直接鍵入命令來做一些管理,例如控制變化間隔時間、排序字段、匯總信息顯示等。

常用的命令有2個。

h:顯示簡要幫助信息。

q:退出top。

注意,在默認情況下,由於只能顯示一個屏幕,因此進程信息是不全的。

輸出信息說明

注意:如果有涉及到內存的但是沒有給出單位,那么單位應該是KB。打算以不同的單位來換算的話,詳見man手冊中的e和E交互式命令。

第一行

第一行輸出的信息,剛好是uptime命令所輸出的信息。詳見下文的uptime命令。

第二行

Tasks: 187 total,   1 running, 186 sleeping,   0 stopped,   0 zombie

系統任務信息匯總,即進程的相關信息。

一共有187個進程,1個在運行,186個處於睡眠狀態,沒有停止和僵屍進程。

第三行

%Cpu(s):  0.0 us,  1.6 sy,  0.0 ni, 98.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

us:表示用戶(user)空間中的進程所占用的CPU資源百分比。這類進程是沒有修改過nice值的,即un-niced。

sy:表示內核空間中的進程所占用的CPU資源百分比。即系統(system)所使用的資源。

ni:表示用戶空間中,調整過nice值得進程所占用的CPU資源百分比。

id:表示CPU處於空閑(idle)狀態的百分比。

wa:表示CPU處於等待IO(IO-wait)狀態的百分比。

hi:表示CPU處於硬中斷時間的百分比。

si:表示CPU處於軟中斷時間的百分比。

st:表示用於虛擬機服務的時間百分比。

第四行

KiB Mem :   997980 total,   133396 free,   464344 used,   400240 buff/cache

這行表示的是物理內存。

total:總內存。

free:完全空閑的內存。

used:真實已使用的內存。

buff/cache:被使用的內存中(不是used),用於buffer或者cache的部分,這部分是還可以再利用的。因此我們看一個系統的物理內存剩余情況,一般要看free+buff/cache的和值。

total=free+used+buff/cache

第五行

KiB Swap:  2097148 total,  2097148 free,        0 used.   318028 avail Mem

swap表示的是交換分區。交換分區一般是物理磁盤上的區域,用於當內存資源不足的時候,系統依據某些算法(如LRU)將內存中數據交換到磁盤中的交換分區上存放。

因此交換分區肯定是系統可以不使用,那是最好的。畢竟物理磁盤的速度遠遠慢於內存。

在man手冊中,也將這部分稱之為了虛擬內存。(存疑)應該是相對於物理內存,所以才這么說的。

前面三個字段很好理解,分別表示了交換分區的總量(total)、剩余(free)和已使用(used)。

在我們的實驗機上,由於沒有負載,物理內存完全夠用,因此這里是完全沒有用到swap分區,這很棒!

avail Mem:表示在不使用交換分區的情況下,如果啟用一個新的程序,那么系統上有多少物理內存資源可用。這是一個近似值。不像free字段,it attempts to account for readily reclaimable page cache and memory slabs. 它和內核的版本也有關系,在3.14上是可用的,在2.6.27+上是仿真的,其他情況下等同於free。

第六行

Change delay from 3.0 to

這行一般情況下是空的,用於命令的提示和鍵入命令等。例如我們交互式命令d用於修改刷新間隔,然后會在該行出現提示,要求我們輸入新的刷新間隔時間。

第七行

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                              
   757 root      20   0   21668   1296    988 S   0.7  0.1   0:00.13 irqbalance                                                                                                           
  2111 root      20   0  161988   2360   1592 R   0.7  0.2   0:00.05 top                                                                                                                  
    37 root      20   0       0      0      0 S   0.3  0.0   0:00.46 kworker/1:1                                                                                                          
   113 root      20   0       0      0      0 S   0.3  0.0   0:00.42 kworker/0:2

常見的就不再說明了。

PR:任務的調度優先級(scheduling priority)。越小越優先。如果值為rt的話,表示任務運行於實時調度優先級下。實時優先級的意思可能是任務總是可以搶占(preempt)CPU的資源。

NI:任務的nice值,越小越優先級。這個值的變化,也會影響到PR。NI值為-20的時候,PR值會為0。

VIRT:虛擬內存的總值。包含了所有的代碼、數據和共享庫,加上被交換出去的頁面和被映射但是還未使用的頁面。

RES:常駐(resident)內存的大小。常駐內存應該才是我們所通常說的內存,而上面的VIRT包含了許多其他的“內存”例如swap等。

SHR:共享(shared)內存的大小。並不是所有的共享內存都是常駐的,它只是反映了潛在地可被共享給其他進程的內存大小。

S:進程狀態。D(不可中斷睡眠)、R(運行)、S(睡眠)、T(被作業控制信號所停止)、t(在追蹤的過程中被調試器所停止)和Z(僵屍進程)。

%CPU:可簡單的理解為CPU占用百分比,不過它是可以超過100%的,具體可見man手冊的字段說明。

%MEM:指物理內存占用的百分比。即常駐內存。

TIME+:和TIME字段的含義是相同的,表示進程占用CPU的總時間,不過該字段的反饋更加細粒度,可精確到百分之一秒。

COMMAND:就是命令了,默認情況下只顯示命令的名稱,可通過交互式命令c來切換命令名稱與命令行的顯示。命令行的意思就是帶參數的完全的命令。顯示命令行的情況下,內核顯示會以中括號的形式顯示,例如“[ksoftirqd/0]”。

選項說明

-v和-h:用於顯示庫版本以及選項使用提示。

# top -v
或者
# top -h
  procps-ng version 3.3.10
Usage:
  top -hv | -bcHiOSs -d secs -n max -u|U user -p pid(s) -o field -w [cols]

top的選項,可以不加連接號(-)或者不需要空格。知道即可,一般不會這么使用。

# top h
# top v

-d #:以指定的時間間隔刷新,單位是秒,默認是3秒。

-b:啟用批處理(batch)模式。默認情況下的top輸出,是輸出到屏幕,並且在每個間隔時間后刷新一次,刷新的數據會覆蓋之前的數據。而啟用批處理模式后,每次輸出都不會進行覆蓋操作,這有利於我們將top的結果輸出到其他程序或文件中。如果結合-n選項的話,可指定批處理模式在運行幾次后自動退出,否則就需要用戶自己鍵入Ctrl+c來退出。批處理模式下顯示的進程信息是全的。

# top -b -n 3

本打算像pgrep/pkill那樣看man手冊來盡可能詳述一下,但是看到top的man手冊如此大的篇幅量,暫且放棄了,列出一些馬哥說的常用的即可。

另外,個人感覺,當內功心法(計算機基礎、英語等)不夠的時候,不可以直接就上來學習一些上乘的武功(比如直接照着一個幾千行的man手冊等)。

排序

M:以%MEM內存字段排序。

N:以PID字段排序。

P:以CPU使用率%CPU字段排序。

T:以使用CPU時間TIME+字段排序。

R:上面說的四個排序字段,默認都是降序排序,想要改變升降序的話,使用R。

匯總信息顯示開關

l:第一行信息的顯示開關。

top - 14:32:16 up  5:18,  2 users,  load average: 0.00, 0.01, 0.05

t:控制任務(即進程)和CPU相關信息的顯示開關。一共有四種顯示模式,下面是第一種。

Tasks: 190 total,   1 running, 189 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

第二種和第三種模式都是將CPU資源按照一個使用進度條來顯示,一種是條狀圖形,另一種是塊狀圖形,我個人實驗環境,沒有什么負載,因此無法看出區別。

Tasks: 189 total,   2 running, 187 sleeping,   0 stopped,   0 zombie
%Cpu(s):   0.0/0.0     0[                                                                                                    ]
Tasks: 189 total,   2 running, 187 sleeping,   0 stopped,   0 zombie
%Cpu(s):   0.0/0.5     0[                                                                                                    ]

第四種就是直接關閉顯示了。在CentOS 6上,則只有開關顯示而已。

m:內存的顯示控制,和t命令一樣,也有四種模式。因為內存的數據比較豐富,就可以看出條狀圖形和塊狀圖形的區別了。

其他命令

s|d:可用於修改top顯示的間隔時間,單位是秒,鍵入數字后回車即可。

k:選擇某個PID並選擇向其發送的信號。PID為0表示top命令自身,默認的信號是15/SIGTERM。

r:調整某個進程的nice值。

 

uptime

顯示的信息,和top的首行信息一致。

[root@C7 ~]# uptime
 15:46:29 up  6:32,  2 users,  load average: 0.00, 0.01, 0.05

15:46:29:表示當前的時間。

up    6:32:表示系統已啟動的時間。可通過-p選項來使得顯示更加直觀。

[root@C7 ~]# uptime -p
up 6 hours, 32 minutes

想知道系統的啟動時間的話,我們可以自己推算,也可以使用-s選項。

[root@C7 ~]# uptime -s
2019-07-19 09:13:51

2 users:表示當前系統在線用戶數。

load average: 0.00, 0.01, 0.05:這個表示系統的平均負載。一共有3個數字。

  • 第一個數字:系統在過去1分鍾內的平均負載。
  • 第二個數字:系統在過去5分鍾內的平均負載。
  • 第三個數字:系統在過去15分鍾內的平均負載。

平均負載表示的是處於可運行態(runnable)或者不可中斷態(uninterruptable)的進程的數量的平均值。可運行態表示的是進程正在使用或者等待使用CPU資源。不可中斷態表示的是進程正處於等待IO的情況,例如磁盤IO。

需要注意的是,平均負載並沒有針對系統的CPU核心數做專門的設計(man手冊叫常規化(normalized))。舉個例子,假設平均負載為1,那么在單核的CPU上就表示系統總是忙碌的,在4核的CPU上就表示系統有75%的時間處於空閑狀態。

因此判斷系統是否繁忙,要將平均負載和CPU核心數結合考量。

 

htop

不知是否是由於htop是基於ncurses,它支持類似GUI的鼠標點擊,如果鼠標點擊在字段名上,還支持排序,反復點擊字段名支持升序和降序。

htop類似於htop,不過它的輸出帶有顯示着色,並且更易看懂。其他的區別,沒實踐過,這里基於man手冊,在這里也說明下。

htop允許水平和垂直方向的滾動,因此可以看到系統上的所有的進程信息,包含完整的命令行信息。可以以進程樹的形式展示進程,可以一次性選擇多個進程並在其上執行一些操作。不需要輸入PID即可kill或者renice進程。

系統上很可能沒htop命令,單獨安裝下。

# yum install htop

界面展示。

-d --delay=DELAY:指定刷新的間隔,默認是1秒刷新一次。這里的單位要注意,它是十分之一秒,也就是說”-d 1“表示每隔0.1秒刷新一次。

# htop -d 50
每隔5秒刷新一次。

-u --user=USERNAME:僅顯示指定用戶的進程。

# htop -u postfix

-s --sort-key COLUMN:以某個指定的字段排序。可以先查看有哪些字段是支持排序的。

[root@C7 ~]# htop -s help
PID
Command
STATE
PPID
...

排序默認是升序。

# htop -s PID

一些交互式命令。

l:查看選定的進程所打開的文件列表。

s:追蹤選定進程的系統調用。

t:以樹狀圖形式顯示進程狀態。

a:設置進程與CPU核心的綁定。

 

vmstat

用於報告虛擬內存統計信息。語法如下。

vmstat [options] [delay [count]]

不帶任何選項和參數的情況下,只顯示一次信息。

[root@C7 ~]# vmstat 
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 137488   2116 400088    0    0    12     1   20   18  0  0 100  0  0

delay:每隔幾秒顯示一次。不支持小數。

count:一共顯示幾次,如果存在delay但是省略count的話,那么將會一直循環輸出。

接下來我們來解釋一下每個字段的含義。

Procs

  • r:可運行的進程數,包含了運行中或者等待運行的。
  • b:處於不可中斷睡眠狀態的進程數。

Memory

  • swpd:虛擬內存的使用數量(這里的虛擬內存,應該就是只swap中的存儲吧?)。
  • free:處於空閑狀態的內存數。
  • buff:作為緩沖(buffer)的內存數。
  • cache:作為緩存(cache)的內存數。

Swap

  • si:從磁盤交換入的內存速率,單位是每秒。
  • so:交換至磁盤的內存速率。

IO

  • bi:從塊設備上接收到的塊數(blocks/s)。
  • bo:發送至塊設備上的塊數(blocks/s)。

System

  • in:每秒中斷數,包含時鍾(clock)。
  • cs:每秒發生的上下文切換數。

CPU

這里記錄的是占CPU時間的百分比。

  • us:運行非內核級代碼的時間。(用戶時間,包含nice時間)
  • sy:運行內核級代碼的時間。(系統時間)
  • id:處於空閑狀態的時間。
  • wa:等待IO的時間。
  • st:被虛擬機所偷走(stolen)的時間。

 

pmap

根據PID查看進程的內存映射情況。

pmap [options] pid [...]

 

-x:查看擴展格式,即更詳細的信息。

# pmap 1
# pmap -x 1

 

也可以直接查看/proc目錄下的文件。

# cat /proc/PID/maps
# cat /proc/1/maps

 

 

glances

是一款類似top和htop的綜合監控工具。跨平台,使用python語言編寫。

最早出現的是top,htop試圖取代top,而glances則試圖取代前兩者。

官網是:https://nicolargo.github.io/glances/

從站點的介紹來看,glances是一款更接近現代的監控系統,社區和文檔都不錯,將來可着重學習。

它除了可以像top/htop那樣獨立運行以外,還支持C/S模式和web模式,並且數據可以到處成csv格式等多種格式,也可以輸出到其他的監控平台如Prometheus等。

 

dstat

dstat是一個多功能的工具,它用於取代vmstat、iostat、ifstat和netstat工具。看man手冊的話,有說明該工具比上述其他工具更好,例如克服了上述工具已知的一些缺點以及添加了一些額外的功能。

也是需要單獨安裝的一個命令。

# yum install dstat

語法。

dstat [-afv] [options..] [delay [count]]

不帶選項和參數的dstat的輸出結果,默認是delay為1秒,count省略無限制,直到用戶Ctrl+c退出。

輸出結果有一個很明顯的特點,也是htop相對於top的特點,那就是着色。並且它還自帶了單位轉換。

由於我們沒有指定任何的選項,因此命令默認幫我們指定了-cdngy這5個選項。

You did not select any stats, using -cdngy by default.

-c, --cpu:啟用CPU統計。

-d, --disk:啟用磁盤統計。

-n, --net:啟用網絡統計。

-g, --page:啟用頁面統計。

-y, --sys:啟用系統統計。

在語法中,還特意將[-afv]列出來了,我們來單獨看這3個選項的作用。

-a, --all:等同於-cdngy,也就是默認的選項。

-f, --full:擴展-C、-D、-I、-N和-S發現列表。我們先來單獨看這幾個大寫的選項的含義。

  • -C 0,3,total:當使用-c選項時,包含cpu0、cpu3和total。
  • -D total,hda:當使用-d選項時,包含total和hda。
  • -I 5,10:當使用-i選項時,包含中斷5和10。
    • -i, --int:啟用中斷統計。
  • -N eth1,total:當使用-n選項時,包含eth1和total。
  • -S swap1,total:當使用-s選項時,包含swap1和total。
    • -s, --swap:啟用swap統計。

默認情況下,我們對於CPU、磁盤和網卡等資源的監控,都是只顯示total信息的。

假如我們在監控CPU信息時(-c),又使用-C選項,就可以實現對具體的某個或者某些CPU核心進行監控。

當然了,這些大寫的選項后面是需要加具體的參數的,否則報錯。

[root@C7 ~]# dstat -c -C
dstat: option -C requires argument, try dstat -h for a list of all the options

而-f選項,則是直接將上述提到的那些指定某些實例(如CPU核心、網卡、硬盤等)的選項都帶上,並且選項參數都默認擴展為系統上已發現的CPU核心、網卡和硬盤等。

簡而言之,-af可以將原本統計total的信息轉變為針對具體實例的統計。

-v, --vmstat:等同於“-pmgdsc -D total”。該選項的統計信息,應該是模仿vmstat的輸出。

-p, --proc:啟用進程統計。

-m, --mem:啟用內存統計。

--tcp:啟用TCP連接相關的統計(listen, established, syn, time_wait, close)。

--udp:啟用TCP連接相關的統計(listen, active)。

--raw:啟用裸套接字相關的統計(raw sockets)。

--socket:啟用套接字相關的統計(total, tcp, udp, raw, ip-fragments)。

--ipc:啟用IPC(進程間通信)相關的統計(message queue, semaphores, shared memory)。

 --output file:以CSV格式寫入到外部文件中。

[root@C7 ~]# cat dstat_along.csv 
"Dstat 0.7.2 CSV output"
"Author:","Dag Wieers <dag@wieers.com>",,,,"URL:","http://dag.wieers.com/home-made/dstat/"
"Host:","C7",,,,"User:","root"
"Cmdline:","dstat --output dstat_along.csv 1 2",,,,"Date:","05 Aug 2019 14:43:30 CST"

"total cpu usage",,,,,,"dsk/total",,"net/total",,"paging",,"system",
"usr","sys","idl","wai","hiq","siq","read","writ","recv","send","in","out","int","csw"
0.020,0.066,99.907,0.006,0.0,0.001,19724.801,2191.394,0.0,0.0,0.0,0.0,72.748,64.299
0.0,0.0,100.0,0.0,0.0,0.0,0.0,0.0,106.0,902.0,0.0,0.0,72.0,55.0
0.249,0.249,99.501,0.0,0.0,0.0,0.0,0.0,60.0,362.0,0.0,0.0,92.0,71.0

--noupdate:當delay大於1的時候,例如3,並不是每隔3秒才會顯示一次,在3秒內的每隔一秒,都會顯示一次中間狀態值,就是下圖中紅色沒加粗的字體。使用該選項的話,會禁用這種機制。

這個中間狀態值是在這段時間內的平均值,而不是快照值。例如delay等於10,那么前9次的值,分別是前1秒的平均值、前2秒的平均值。。。前9秒的平均值。最后的值,是前10秒的平均值。

dstat中可包含插件用於擴展其功能,插件有內部和外部之分,用戶可自行開發插件或者參與到插件的開發(contribute,貢獻)。

內部插件應該是dstat自帶的。外部插件才是用戶開發的。

--list:列出內部和外部插件。

[root@C7 ~]# dstat --list
internal:
    aio, cpu, cpu24, disk, disk24, disk24old, epoch, fs, int, int24, io, ipc, load, lock, mem, net, page, page24, proc, raw, socket, swap, swapold, sys, tcp, time, udp, unix, vm
/usr/share/dstat:
    battery, battery-remain, cpufreq, dbus, disk-tps, disk-util, dstat, dstat-cpu, dstat-ctxt, dstat-mem, fan, freespace, gpfs, gpfs-ops, helloworld, innodb-buffer, innodb-io, 
    innodb-ops, lustre, memcache-hits, mysql-io, mysql-keys, mysql5-cmds, mysql5-conn, mysql5-io, mysql5-keys, net-packets, nfs3, nfs3-ops, nfsd3, nfsd3-ops, ntp, postfix, power, 
    proc-count, qmail, rpc, rpcd, sendmail, snooze, squid, test, thermal, top-bio, top-bio-adv, top-childwait, top-cpu, top-cpu-adv, top-cputime, top-cputime-avg, top-int, top-io, 
    top-io-adv, top-latency, top-latency-avg, top-mem, top-oom, utmp, vm-memctl, vmk-hba, vmk-int, vmk-nic, vz-cpu, vz-io, vz-ubc, wifi

--plugin-name:基於插件的名稱來啟用外部插件。這里的“--plugin-name”是需要替換成具體的插件名稱的。這些在man手冊的PLUGINS中可查看具體的每個插件名稱。

例如--dbus和--dstat。

而有一些插件,則是需要其他條件的支持才可使用的。

[root@C7 ~]# dstat --battery 1 2
Module dstat_battery failed to load. (No ACPI battery information found.)
None of the stats you selected are available.

dstat支持一些top系列的插件,用於顯示最占用某些資源的進程。

--top-cpu:顯示最占用CPU的進程。

--top-mem:顯示最占用內存的進程。

--top-oom:顯示當內存不足時,顯示最容易被OOM機制所kill掉的進程,這個在內存不足時還是蠻有用的。

--top-io:顯示最占用IO的進程。

--top-latency:顯示延遲最高的進程,單位毫秒。

-t, --time:在輸出的時候,加上當前的日期和時間信息,某些情況下可能有用。該選項一般放最前。

 

kill和killall

進程間通信,包含了信號(signal)機制。而kill命令,則用於向進程發送信號。

不過需要注意的是,kill命令,有2個,一個是bash內置命令,另一個是外部命令。

當我們直接鍵入kill命令的時候,就是使用內置命令。

可通過type命令來判斷。

[root@C7 ~]# type kill
kill is a shell builtin

想使用外部的kill命令的話,可通過which來判斷其絕對路徑,然后鍵入絕對路徑來執行。

[root@C7 ~]# which kill
/usr/bin/kill

查看內置命令用法使用help命令,查看外部命令用法使用man命令。

# help kill
# man kill

查看完幫助后,發現外部kill命令有--help選項,而內置的kill命令是沒有的,因此可使用該選項來判斷你所使用的到底是內置還是外部。

[root@C7 ~]# kill --help
-bash: kill: -help: invalid signal specification
[root@C7 ~]# /usr/bin/kill --help
... ...

本文所闡述的是內置的kill命令。

kill命令會成為shell內置命令有兩點原因。

  1. 它允許了作業(job)ID可以被使用,而不僅僅是PID。
  2. 它允許用戶在系統進程數已達到最大值的時候依然可以kill進程。注:若使用的是外部命令,則必須再發起一個新進程,而此時由於達到了進程上限,因此無法再發起新進程也就無法再使用外部命令了。而內置命令存在於當前shell進程中,無需再創建新進程。

-l:列出所有的信號。

[root@C7 ~]# kill -l
 1) SIGHUP     2) SIGINT     3) SIGQUIT     4) SIGILL     5) SIGTRAP
 6) SIGABRT     7) SIGBUS     8) SIGFPE     9) SIGKILL    10) SIGUSR1
11) SIGSEGV    12) SIGUSR2    13) SIGPIPE    14) SIGALRM    15) SIGTERM
16) SIGSTKFLT    17) SIGCHLD    18) SIGCONT    19) SIGSTOP    20) SIGTSTP
21) SIGTTIN    22) SIGTTOU    23) SIGURG    24) SIGXCPU    25) SIGXFSZ
26) SIGVTALRM    27) SIGPROF    28) SIGWINCH    29) SIGIO    30) SIGPWR
31) SIGSYS    34) SIGRTMIN    35) SIGRTMIN+1    36) SIGRTMIN+2    37) SIGRTMIN+3
38) SIGRTMIN+4    39) SIGRTMIN+5    40) SIGRTMIN+6    41) SIGRTMIN+7    42) SIGRTMIN+8
43) SIGRTMIN+9    44) SIGRTMIN+10    45) SIGRTMIN+11    46) SIGRTMIN+12    47) SIGRTMIN+13
48) SIGRTMIN+14    49) SIGRTMIN+15    50) SIGRTMAX-14    51) SIGRTMAX-13    52) SIGRTMAX-12
53) SIGRTMAX-11    54) SIGRTMAX-10    55) SIGRTMAX-9    56) SIGRTMAX-8    57) SIGRTMAX-7
58) SIGRTMAX-6    59) SIGRTMAX-5    60) SIGRTMAX-4    61) SIGRTMAX-3    62) SIGRTMAX-2
63) SIGRTMAX-1    64) SIGRTMAX

信號的表示方法有三種。

  • 數字,例如1。
  • 完整名稱,例如SIGHUP。
  • 簡寫名稱,例如HUP。
# kill -s 15 PID
# kill -s SIGTERM PID
# kill -s TERM PID

常用的信號:

  • 1(SIGHUP):在不停止進程的情況下使其重載配置文件;一般的服務的reload函數就是調用此命令;
  • 2(SIGINT):interrupt,打斷正在運行的進程,等同於在終端鍵入Ctrl + c;
  • 9(SIGKILL):直接殺死正在運行的進程;
  • 15(SIGTERM):終止運行中的進程;一般的服務的stop函數就是調用此命令(個人見解);這是默認的信號;
  • 18(SIGCONT):繼續被停止的進程;
  • 19(SIGSTOP):停止進程,等同於在進程運行時鍵入Ctrl + z或者命令執行的時候加入后台符號&;

kill基於PID來向進程發送信號,而killall則可以根據進程名來發送信號。和kill類似,其默認的信號是SIGTERM,-s選項用於指定信號。

其作用應該是和pkill一樣的,不過默認情況下pkill的進程名是模糊匹配,而killall則必須完全匹配進程名。

[root@C7 ~]# ps axu | grep -E "redis|httpd"
redis      2996  0.1  0.5 142956  5796 ?        Ssl  15:11   0:00 /usr/bin/redis-server 127.0.0.1:6379
root       3028  0.0  0.5 230376  5164 ?        Ss   15:12   0:00 /usr/sbin/httpd -DFOREGROUND
apache     3045  0.0  0.3 232460  3148 ?        S    15:13   0:00 /usr/sbin/httpd -DFOREGROUND
apache     3046  0.0  0.3 232460  3148 ?        S    15:13   0:00 /usr/sbin/httpd -DFOREGROUND
apache     3047  0.0  0.3 232460  3148 ?        S    15:13   0:00 /usr/sbin/httpd -DFOREGROUND
apache     3048  0.0  0.3 232460  3148 ?        S    15:13   0:00 /usr/sbin/httpd -DFOREGROUND
apache     3050  0.0  0.3 232460  3148 ?        S    15:13   0:00 /usr/sbin/httpd -DFOREGROUND
root       3113  0.0  0.0 112708   988 pts/1    S+   15:17   0:00 grep --color=auto -E redis|httpd
[root@C7 ~]# killall http
http: no process found
[root@C7 ~]# killall httpd
[root@C7 ~]# killall redis
redis: no process found
[root@C7 ~]# killall redis-server
[root@C7 ~]# ps axu | grep -E "redis|httpd"
root       3149  0.0  0.0 112708   988 pts/1    S+   15:18   0:00 grep --color=auto -E redis|httpd

想要改變killall的匹配進程名的規則,例如啟用RE;或者想根據安全上下文(涉及selinux)、用戶名來向進程發送信號。這些,killall都是支持的,詳見man手冊中的選項說明。

 

結語

還有許許多多和進程相關的其他命令。

  • 進程作業(job)系統:jobs、bg、fg。
  • 進程優先級:nice、renice。

該篇篇幅太長了,就不展開了。另外,也感慨雖然這篇隨筆的篇幅很長,但是大多是比較凌亂的知識點,並且個人對其准確性也不敢完全保證。

並且深度也不夠,慚愧慚愧,權當筆記了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM