转:ps命令详解


  • ps :將某個時間點的程序運作情況擷取下來
[root@www ~]# ps aux  <==觀察系統所有的程序資料
[root@www ~]# ps -lA  <==也是能夠觀察所有系統的資料
[root@www ~]# ps axjf <==連同部分程序樹狀態
選項與參數:
-A  :所有的 process 均顯示出來,與 -e 具有同樣的效用;
-a  :不與 terminal 有關的所有 process ;
-u  :有效使用者 (effective user) 相關的 process ;
x   :通常與 a 這個參數一起使用,可列出較完整資訊。
輸出格式規劃:
l   :較長、較詳細的將該 PID 的的資訊列出;
j   :工作的格式 (jobs format)
-f  :做一個更為完整的輸出。

鳥哥個人認為 ps 這個指令的 man page 不是很好查閱,因為很多不同的 Unix 都使用這個 ps 來查閱程序狀態, 為了要符合不同版本的需求,所以這個 man page 寫的非常的龐大!因此,通常鳥哥都會建議你,直接背兩個比較不同的選項, 一個是只能查閱自己 bash 程序的『 ps -l 』一個則是可以查閱所有系統運作的程序『 ps aux 』!注意,你沒看錯,是『 ps aux 』沒有那個減號 (-) !先來看看關於自己 bash 程序狀態的觀察:

  • 僅觀察自己的 bash 相關程序: ps -l
範例一:將目前屬於您自己這次登入的 PID 與相關資訊列示出來(只與自己的 bash 有關)
[root@www ~]# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0 13639 13637  0  75   0 -  1287 wait   pts/1    00:00:00 bash
4 R     0 13700 13639  0  77   0 -  1101 -      pts/1    00:00:00 ps

系統整體的程序運作是非常多的,但如果使用 ps -l 則僅列出與你的操作環境 (bash) 有關的程序而已, 亦即最上層的父程序會是你自己的 bash 而沒有延伸到 init 這支程序去!那麼 ps -l 秀出來的資料有哪些呢? 我們就來觀察看看:

  • F:代表這個程序旗標 (process flags),說明這個程序的總結權限,常見號碼有:
  • S:代表這個程序的狀態 (STAT),主要的狀態有:
    • R (Running):該程式正在運作中;
    • S (Sleep):該程式目前正在睡眠狀態(idle),但可以被喚醒(signal)。
    • D :不可被喚醒的睡眠狀態,通常這支程式可能在等待 I/O 的情況(ex>列印)
    • T :停止狀態(stop),可能是在工作控制(背景暫停)或除錯 (traced) 狀態;
    • Z (Zombie):僵屍狀態,程序已經終止但卻無法被移除至記憶體外。
  • UID/PID/PPID:代表『此程序被該 UID 所擁有/程序的 PID 號碼/此程序的父程序 PID 號碼』
  • C:代表 CPU 使用率,單位為百分比;
  • PRI/NI:Priority/Nice 的縮寫,代表此程序被 CPU 所執行的優先順序,數值越小代表該程序越快被 CPU 執行。詳細的 PRI 與 NI 將在下一小節說明。
  • ADDR/SZ/WCHAN:都與記憶體有關,ADDR 是 kernel function,指出該程序在記憶體的哪個部分,如果是個 running 的程序,一般就會顯示『 - 』 / SZ 代表此程序用掉多少記憶體 / WCHAN 表示目前程序是否運作中,同樣的, 若為 - 表示正在運作中。
  • TTY:登入者的終端機位置,若為遠端登入則使用動態終端介面 (pts/n);
  • TIME:使用掉的 CPU 時間,注意,是此程序實際花費 CPU 運作的時間,而不是系統時間;
  • CMD:就是 command 的縮寫,造成此程序的觸發程式之指令為何。

所以你看到的 ps -l 輸出訊息中,他說明的是:『bash 的程式屬於 UID 為 0 的使用者,狀態為睡眠 (sleep), 之所以為睡眠因為他觸發了 ps (狀態為 run) 之故。此程序的 PID 為 13639,優先執行順序為 75 , 下達 bash 所取得的終端介面為 pts/1 ,運作狀態為等待 (wait) 。』這樣已經夠清楚了吧? 您自己嘗試解析一下那麼 ps 那一行代表的意義為何呢? ^_^

接下來讓我們使用 ps 來觀察一下系統內所有的程序狀態吧!

  • 觀察系統所有程序: ps aux
範例二:列出目前所有的正在記憶體當中的程序:
[root@www ~]# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   2064   616 ?        Ss   Mar11   0:01 init [5]
root         2  0.0  0.0      0     0 ?        S<   Mar11   0:00 [migration/0]
root         3  0.0  0.0      0     0 ?        SN   Mar11   0:00 [ksoftirqd/0]
.....(中間省略).....
root     13639  0.0  0.2   5148  1508 pts/1    Ss   11:44   0:00 -bash
root     14232  0.0  0.1   4452   876 pts/1    R+   15:52   0:00 ps aux
root     18593  0.0  0.0   2240   476 ?        Ss   Mar14   0:00 /usr/sbin/atd

你會發現 ps -l 與 ps aux 顯示的項目並不相同!在 ps aux 顯示的項目中,各欄位的意義為:

  • USER:該 process 屬於那個使用者帳號的?
  • PID :該 process 的程序識別碼。
  • %CPU:該 process 使用掉的 CPU 資源百分比;
  • %MEM:該 process 所佔用的實體記憶體百分比;
  • VSZ :該 process 使用掉的虛擬記憶體量 (Kbytes)
  • RSS :該 process 佔用的固定的記憶體量 (Kbytes)
  • TTY :該 process 是在那個終端機上面運作,若與終端機無關則顯示 ?,另外, tty1-tty6 是本機上面的登入者程序,若為 pts/0 等等的,則表示為由網路連接進主機的程序。
  • STAT:該程序目前的狀態,狀態顯示與 ps -l 的 S 旗標相同 (R/S/T/Z)
  • START:該 process 被觸發啟動的時間;
  • TIME :該 process 實際使用 CPU 運作的時間。
  • COMMAND:該程序的實際指令為何?

一般來說,ps aux 會依照 PID 的順序來排序顯示,我們還是以 13639 那個 PID 那行來說明!該行的意義為『 root 執行的 bash PID 為 13639,佔用了 0.2% 的記憶體容量百分比,狀態為休眠 (S),該程序啟動的時間為 11:44 , 且取得的終端機環境為 pts/1 。』與 ps aux 看到的其實是同一個程序啦!這樣可以理解嗎? 讓我們繼續使用 ps 來觀察一下其他的資訊吧!

範例三:以範例一的顯示內容,顯示出所有的程序:
[root@www ~]# ps -lA
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0     1     0  0  76   0 -   435 -      ?        00:00:01 init
1 S     0     2     1  0  94  19 -     0 ksofti ?        00:00:00 ksoftirqd/0
1 S     0     3     1  0  70  -5 -     0 worker ?        00:00:00 events/0
....(以下省略)....
# 你會發現每個欄位與 ps -l 的輸出情況相同,但顯示的程序則包括系統所有的程序。

範例四:列出類似程序樹的程序顯示:
[root@www ~]# ps axjf
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    0     1     1     1 ?           -1 Ss       0   0:01 init [5]
.....(中間省略).....
    1  4586  4586  4586 ?           -1 Ss       0   0:00 /usr/sbin/sshd
 4586 13637 13637 13637 ?           -1 Ss       0   0:00  \_ sshd: root@pts/1
13637 13639 13639 13639 pts/1    14266 Ss       0   0:00      \_ -bash
13639 14266 14266 13639 pts/1    14266 R+       0   0:00          \_ ps axjf
.....(後面省略).....

看出來了吧?其實鳥哥在進行一些測試時,都是以網路連線進主機來測試的,所以囉,你會發現其實程序之間是有相關性的啦! 不過,其實還可以使用 pstree 來達成這個程序樹喔!以上面的例子來看,鳥哥是透過 sshd 提供的網路服務取得一個程序, 該程序提供 bash 給我使用,而我透過 bash 再去執行 ps axjf !這樣可以看的懂了嗎?其他各欄位的意義請 man ps (雖然真的很難 man 的出來!) 囉!

範例五:找出與 cron 與 syslog 這兩個服務有關的 PID 號碼?
[root@www ~]# ps aux | egrep '(cron|syslog)'
root   4286  0.0  0.0  1720   572 ?      Ss  Mar11   0:00 syslogd -m 0
root   4661  0.0  0.1  5500  1192 ?      Ss  Mar11   0:00 crond
root  14286  0.0  0.0  4116   592 pts/1  R+  16:15   0:00 egrep (cron|syslog)
# 所以號碼是 4286 及 4661 這兩個囉!就是這樣找的啦!

除此之外,我們必須要知道的是『僵屍 (zombie) 』程序是什麼? 通常,造成僵屍程序的成因是因為該程序應該已經執行完畢,或者是因故應該要終止了, 但是該程序的父程序卻無法完整的將該程序結束掉,而造成那個程序一直存在記憶體當中。 如果你發現在某個程序的 CMD 後面還接上 <defunct> 時,就代表該程序是僵屍程序啦,例如:

apache  8683  0.0  0.9 83384 9992 ?   Z  14:33   0:00 /usr/sbin/httpd <defunct>

當系統不穩定的時候就容易造成所謂的僵屍程序,可能是因為程式寫的不好啦,或者是使用者的操作習慣不良等等所造成。 如果你發現系統中很多僵屍程序時,記得啊!要找出該程序的父程序,然後好好的做個追蹤,好好的進行主機的環境最佳化啊! 看看有什麼地方需要改善的,不要只是直接將他 kill 掉而已呢!不然的話,萬一他一直產生,那可就麻煩了! @_@

事實上,通常僵屍程序都已經無法控管,而直接是交給 init 這支程式來負責了,偏偏 init 是系統第一支執行的程式, 他是所有程式的父程式!我們無法殺掉該程式的 (殺掉他,系統就死掉了!),所以囉,如果產生僵屍程序, 而系統過一陣子還沒有辦法透過核心非經常性的特殊處理來將該程序刪除時,那你只好透過 reboot 的方式來將該程序抹去了!

http://linux.vbird.org/linux_basic/0440processcontrol.php#ps

Archives