原文連接:blog.csdn.net/juS3Ve/arti…linux
大概在十多年前,我當時仍是一個產品經理。因爲一些工做的緣由,須要向運維工程師學習一些 linux 經常使用命令。當使用 linux ps 這個十分經常使用的命令時,遇到了一個小小的疑惑。有些工程師推薦使用 ps aux 的命令組合,有些工程師推薦使用 ps -aux 的命令組合,從輸出結果上來看彷佛也沒有什麼不一樣。考慮到如經常使用的 ls -l 命令在內,不少 linux 命令選項前都要加上一個短橫線,這麼來看彷佛 ps -axu 是正確的。可是一些早期的 linux 版本,在執行 ps -axu 時又會報出以下錯誤 Warning: bad syntax,而 ps aux 卻沒有這樣的報錯信息,這麼看來彷佛 ps aux 又是正確的。查閱市面上的一些 linux 書籍,在介紹 linux ps 命令示例時,有些說用 ps aux,而有些又說用 ps -axu。實在是讓我這個初學者摸不着頭腦。ios
再後來,隨着我加入運維團隊對 linux ps 命令逐步深刻使用,學會了查看 man page 和 help,發現其中有 ps 命令的 exmaple,果真是 ps aux 的用法是正確的。不過隨着對 linux ps 命令使用的逐步深刻,對 ps 命令的其餘疑問愈來愈多。好比,咱們每天在使用 ps 命令時輸出的 %CPU 列究竟是什麼含義?爲何和 top 顯示的 %CPU 的值有時候差別很是大?再好比,當我使用 ps -el 命令時,爲何個人進程名是 systemd-journald,而 ps 命令只顯示 systemd-journal,弄丟了最後 1 個字母 d。程序員
帶着這麼多疑惑,3 年多前我有機會簡單的學習了一下 linux ps 源代碼,逐步解開了上面這些疑惑。後來發現公司的不少同事也對 ps 命令有各類問題和疑問,因而想把以前對 ps 命令的學習經驗總結成文檔,供你們參考。但願能給你們帶來幫助。算法
Linux ps 命令功能很強大,瞭解 ps 命令首先須要從 ps 命令的選項格式入手。像其餘不少 linux shell 命令同樣,ps 命令的選項也有長格式和短格式的區別。短選項中也能夠帶中橫線、也能夠不帶中橫線。shell
根據選項長短和是否有橫線的狀況,ps 命令的選項能夠分爲如下 3 類:數據庫
BSD 風格語法,必須不能以中橫線開頭;編程
SYSV 風格語法,必須僅一箇中橫線開頭;centos
GNU 風格語法,必須以兩個中橫線開頭;數組
不過 linux ps 命令的長選項並很少,並且幾乎每一個長選項都有一個功能徹底相同的短選項對應。在 centos7 環境運行以下命令能夠見。安全
在本文中咱們將主要介紹 BSD 和 SYSV 兩種風格的 ps 命令選項。若是你們有對 GNU 風格的長選項使用的需求,那麼能夠參考對應的短選項語法便可。須要注意的是 GNU 風格選項都是帶參數值的,例如 --sid 1。
各風格的 ps 命令選項能夠混合使用,好比:
Linux ps 命令解析 SYSV 和 BSD 風格選項時,會分別將每組字符串都解析成單獨的字母。如下三個實例,拆分先後的命令都是等價的。
從示例中能夠看出,當 SYSV 風格語法一箇中橫線以後有多個字母選項時,拆分後須要給每個字母前都加上一個中橫線。也就是說 - elL 轉換爲 - e -l -L,而不是轉換爲 - e l L。
從上面例子中也能夠看出,ps 命令選項除了有是否加中橫線的區別,字母大小寫也表現爲不一樣的選項含義。英文字母一共 26 個,SYSV 風格選項 - A 到 - Z 和 - a 到 - z 共 52 個,BSD 風格選項 A 到 Z 和 a 到 z 共 52 個。因而 ps 命令就有一共 104 個命令選項可能性。
不一樣版本的 ps 命令選項的使用可能略有出入,本文主要使用主流的 centos7 上的 procps-ng version 3.3.10 版原本說明。在這 104 個命令選項中,未啓用的或曾經使用過如今廢棄的命令選項有以下 40 個,分別是 A、B、C、D、E、F、G、I、J、K、P、Q、R、W、Y、b、d、i、y、z、-B、-D、-E、-I、-J、-K、-Q、-R、-S、-W、-X、-Y、-b、-h、-i、-k、-r、-v、-x 和 - z。
既然是未啓用或已廢棄,那麼運行帶這個選項的 ps 命令應該會報錯。試運行下大部分確實如此,不過也有幾個例外,好比 ps -x 命令就不報錯,能夠正常輸出。這樣的例外選項一共有以下 7 個 - S、-X、-h、-k、-r、-v 和 - x,本文第九節會給予說明。
這 104 個命令選項中的其他 64 個選項就構成了 linux ps 命令的龐大命令選項體系,接下的內容就對他們分別給予介紹。
要查看咱們當前 ps 命令的版本,就用到 V、-V 這 2 個選項。
爲了本文中意思表達更加準確,這裏借用數據庫中的幾個概念。ps 命令輸出結果,約定爲結果集。結果集中的每一行,咱們約定爲記錄 (record)。結果集或記錄中的每一列,咱們約定爲字段 (field)。
差很少每個工程師使用 ps 命令時應該都有這樣的疑問, 使用 ps aux 時輸出結果中記錄行數要遠大於只使用 ps 命令時(以下所示)。這其實會讓不少工程師在使用 ps 命令查找須要的進程時內心很忐忑,會不會因爲命令的選項使用不當致使 ps 沒有列出所須要的進程信息。正是這個緣由,咱們首先須要搞懂 ps 命令影響記錄行數的那些選項。
Linux ps 命令的記錄類選項大概有 20 幾個之多。有些能夠列出全部的進程信息,有些按某種規則篩選顯示部分進程信息。現在操做系統中 awk、sed 和 grep 這些 shell 文本處理命令的功能都十分強大,咱們重點仍是掌握 ps 命令中那些顯示全部進程信息記錄的選項,其餘 ps 命令過濾選項均可以經過 shell 文本處理命令(awk、sed 和 grep)間接實現。
Linux ps 命令顯示全部進程信息的選項只有 2 個,即 SYSV 風格的 - e 和 - A。相比之下,-e 更容易記憶和書寫,請你們牢記這個 - e 選項。
你們知道,ps 命令的全部信息都是 linux kernel 生成,並經過 / proc / 目錄輸出給用戶空間的。在 / proc / 目錄下,每個以數字開頭的目錄,就對應一個進程信息。既然如此,經過以下命令即可一目瞭然。
參數 - e 和 - A 顯示的進程記錄數確實和 proc 目錄下的全部進程目錄數一致。
Linux ps 命令的 simple_select 選項一共 5 個,具體包括 - a、-d、a、g 和 x。他們包括 2 個 SYSV 風格和 3 個 BSD 風格選項。2 個 SYSV 風格和 3 個 BSD 風格的選項不能同時使用,不然會報錯。2 個 SYSV 風格或 3 個 BSD 風格內部能夠組合使用,具體的組合可能性有 - ad、ga、ax、gx、agx。這裏值得注意的是這種字母組合選項絕對不是單字母選項篩選規則的簡單組合,ps 命令給這幾種組合賦予了新的篩選規則。
Linux 環境下的 ps 命令,會對 BSD 風格 simple_select 選項部分作 2 個特殊處理:
在原來的 BSD 風格 simple_select 狀況下,再額外增長一個 g 選項;
若是已經有 a、g 和 x 三個選項都出現了,那麼就直接替換爲 - e 選項;
按照這 2 個特殊處理規則,ps aux 選項組合等價於 ps auxg,等價於 ps agx u,等價於 ps -e u。
總結下來,ps 命令 simple_select 選項只有 6 種組合狀況 - a、-d、-ad、g、ga、gx。每一種選項都賦予一個位圖值。ps 命令經過位圖計算來實現它的篩選規則。好比 g 選項的位圖值 select_bits 是 0x0a0a,下面以 g 選項爲例說明。
關於 八、四、二、1 的含義(關於 tty、session、tgid 和 euid 字段含義參考第七節):
「8」 tty 值等於當前進程 tty 值的進程;
「4」 tty 值爲空的進程;
「2」 session 值等於當前進程 tgid(pid) 值的進程;
「1」 euid 值等於當前進程 euid 值的進程;
很明顯 「4」 這位都缺失,1 這位都存在,那麼 g 選項的含義就是:顯示全部 tty 值存在的且 euid 值等於當前進程 euid 值的進程。對此持懷疑態度的同窗能夠經過以下 2 個命令進行驗證。
一樣的分析方法,其餘幾個選項和選項組合的含義:
選項 - a 含義:顯示全部 tty 值存在的且 session 值不等於當前進程 tgid(pid) 值的進程;
選項 - d 含義:顯示全部 session 值不等於當前進程 tgid(pid) 值的進程;
選項組合 - ad 含義:顯示全部 tty 值存在的或 session 值不等於當前進程 tgid(pid) 值的進程。換句話說,被過濾掉的是全部 tty 值爲空的且 session 值等於當前進程 tgid(pid) 值的進程;
選項組合 ga(或選項 a)含義:顯示全部 tty 值存在的進程;
選項組合 gx(或選項 x)含義:顯示全部 euid 值等於當前進程 euid 值的進程;
這類選項比較容易理解,都是根據進程的某個屬性值對進程進行篩選。他們大多須要一個選項的參數,並且也都有功能徹底同樣的 GNU 風格的長選項對應。此類選項一共 13 個,主要分爲以下幾組:
這些選項不但能夠單獨使用,還能夠組合使用(以下所示)。須要注意的是這些選項之間的組合是邏輯或的關係,即或者符合 - u 選項條件或者符合 - p 選項條件。
本節前幾部分全面的介紹了記錄篩選類選項,本小節將對這些選項的綜合做用順序進行一個系統介紹。
記錄類選項是對 / proc / 目錄下的進程信息逐條篩選過濾的:
首先判斷是否有 all_processes 選項。若是有 all_processes 選項,則本條記錄被選擇。若是沒有 all_processes 選項,則繼續下一規則。
其次判斷是否有 simple_select 選項。若是有 simple_select 選項,則使用 simple_select 選項規則判斷本條記錄是否被選中。若是沒有被 simple_select 選項選擇,則繼續下一條規則。
而後判斷是否有 selection_list 選項。若是有 selection_list 選項,則使用 selection_list 選項判斷本條記錄是否被選中。若是沒有 selection_list 選項,則繼續下一條規則。
而後判斷選項中是否有 BSD 風格的選項。若是有 BSD 風格選項,則使用 simple_select 類的選項 g 規則判斷本條記錄是否被選中。若是沒有 BSD 風格選項,則進入下一條規則。
此時不論 ps 命令有 SYSV 風格選項仍是僅無選項 ps 命令,都會使用一個新的 simple_select 選項位圖進行篩選過濾,位圖值爲 0xaa00。若是尚未被選中,則完全失去被選中的機會。位圖值 0xaa00 的意義是:全部 tty 值等於當前進程 tty 的且 euid 值等於當前進程 euid 值的進程。
接下來再看是否有 r 選項。若是有 r 選項則以上 5 個環節被選中的記錄中,只有 R 和 D 狀態的記錄才能被繼續選中。若是沒有 r 選項,則以上 5 個環節中被選中的記錄,都繼續被選中。
最後看是否有 - N 選項,若是有 - N 選項則以上第 6 個環節選中的將不被選中,第 6 個環節未選中的將被選中。若是沒有 - N 選項,則以上第 6 個環節中被選中的記錄,還繼續被選中。
選項 h 單獨生效,若是有 h 選項則取消結果集的標題欄,若是沒有 h 選項則標題欄保持輸出。
上面一章介紹了記錄類選項的使用,瞭解瞭如何篩選符合咱們要求的記錄集。若是咱們須要對輸出結果進行排序,那麼 ps 命令也給咱們提供了 3 個選項,分別是 k、f 和 - H。
選項 k 可讓咱們以某個字段爲條件對輸出結果進行排序,而且還可使用 +- 符號設置升序排序仍是降序排序。
選項 k 還可使用多個字段同時對結果集排序,從輸出結果能夠看到,先按 ppid 進行升序排序,ppid 值相同時,再按 rss 值進行升序排序。
每個進程都有一個父進程,全部用戶空間的進程的最終父進程都是 1 號進程,全部內核空間的線程的最終父線程都是 2 號線程。這樣全部進程按照父子進程的關係就能夠構成 2 個樹形結構。選項 f 和 - H 就是實現這個樹形排序功能的 2 個選項。
從上面的結果中不難看出,選項 f 是使用 ACSII 碼對父子進程進行關聯,選項 - H 是使用 tab 空格對父子進程進行關聯。
前面章節主要是說明了如何篩選和顯示進程的信息。同一個進程有時候還會起多個線程,一樣內核也在 / proc / 目錄下顯示了進程的線程信息,以下所示。
Linux ps 一樣提供了一組選項能夠將每一個進程的線程信息詳細展示,這組選項包括 H、-L、-T、M、m 和 - m。在講解這些選項以前,咱們先看一個小測試。
一樣爲了統計的準確,用 h 選項去掉標題欄信息。其中最後一個 486 的值是 ps -e h 的記錄數,說明當前系統有 486 個進程。很是巧的是 486 恰巧等於 1217 減去 731 的值。從這裏咱們能夠了解到 H、-L 和 - T 這 3 個選項記錄數都是 731,M、m 和 - m 三個選項記錄數都是 1217。找一個起了多線程的進程查看下具體輸出內容。
選項 - L 的輸出能夠看到一共 4 行輸出結果,第一行 PID 等於 LWP(線程 ID)的值,說明是線程組的主線程(即進程)。其他三個線程 ID 各不相同,但 PID 值都和主線程的 PID 值同樣,說明是同一線程組的普通線程。
第二組三個選項單純的顯示不便識別,咱們這裏先引入一個後面講解的 O 選項,額外增長一個輸出值 LWP。
能夠看到一共 5 行輸出結果,對照上面的輸出咱們能夠判斷出,第二組選項除了把線程組中的 4 個線程分別顯示以外,又額外增長了一行內容專門用於顯示這個線程組(即進程)的信息。咱們再回頭看前面的 1271 減去 731 等於 486 應該就很容易明白了。
在 H、-L 和 - T 之間,以及 M、m 和 - m 之間,輸出信息也略有不一樣,不過這些都是數據項和格式的不一樣,後面有專門章節介紹。
不少人在使用 ps 命令時都會注意到,在咱們輸入不一樣的命令組合時,ps 命令輸出結果中列的數據項並不統一。好比下面 2 個命令。
Linux ps 命令的 aux 選項組合輸出 PID、%CPU、%MEM、RSS、TIME 等數據項,ps 命令的 - el 選項組合輸出 PID、PPID、WCHAN、TIME、CMD 等數據項。首先一個問題就是,ps 命令一共有多少數據項能夠輸出。這個問題很好回答,經過 L 選項很容易獲取,一共有 168 個數據輸出項。
其次的一個問題就是,是什麼決定了 ps aux 命令輸出結果中偏偏包含 USER、PID、%CPU、%MEM、VSZ、RSS、TTY、STAT、START、TIME 和 COMMAND 這 11 個數據項呢。緣由是 ps 命令中有一些選項用來對數據字段進行固定組合的做用。其中 aux 中的 u 選項就固定包含了以上 11 個數據輸出項,而且他們的顯示順序也已經固化在代碼中。
Linux ps 命令這種字段組合類選項一共 15 個。其中 6 個選項用途比較普遍,其他 9 個選項都主要適合在查詢某一種問題時使用。
本小節先介紹 6 個通用選項:
本小節先介紹 9 個適合特殊用途的專用選項:
也許有人已經觀察到了,以上字段組合選項,不論哪一個都會固定的有幾個字段老是出現,好比 PID、TTY、TIME 和 CMD 等。下面請你們先看一下這幾個例子。
從以上例子中,咱們能夠得出幾個信息。參數爲 BSD 風格時,默認都會顯示 PID、TTY、STAT、TIME 和 COMMAND 這 5 個字段。參數爲 SYSV 風格時,默認都會顯示 PID、TTY、TIME 和 CMD 這 4 個字段。ps 命令無參數時默認爲 SYSV 風格。
上一小節字段組合選項是 ps 命令爲了一些經常使用場景固化在代碼中的固定數據項組合。可是若是以上全部組合都不知足咱們的要求,或者咱們爲了提高 ps 命令運行效率僅僅須要個別的數據項輸出。那麼咱們能夠經過 - o 或 o 選項來實現自定義數據項的輸出功能。好比咱們對 ps j 這個命令字段組合的輸出信息不滿意,咱們自定義他的輸出。
前文提到過,ps 命令一共能夠輸出 168 個字段,ps L 命令能夠顯示這 168 個字段的詳細狀況。第一列小寫字母是 - o 選項的參數,能夠經過逗號隔開。第二列大寫字母是 ps 命令輸出的結果集標題欄名稱。
儘管大部分狀況下 - o 參數和標題欄都僅僅是大小寫的轉換關係,但也有不那麼完美的時候,以進程的執行命令字段爲例。
這個例子至少能夠說明兩點,不一樣的說明符 (specifier,-o 選項參數) 可能輸出一樣的標題欄。儘管標題欄同樣,但顯示的內容多是有區別的。
有些說明符還提供縮寫,下表是 ps 命令有縮寫的說明符和縮寫的對應關係表,一共 15 個。
有了說明符的縮寫以後,能夠對自定義字段的輸出字段之間添加自定義分隔符。區別於以往 ps 命令各輸出字段都是使用空格做爲分割,使用自定義分隔符以後將更方便使用 shell 數據處理命令進行解析。
前文提到全部字段組合選項都默認包含 4 個或 5 字段。若是想在自定義字段組合時也默認添加一些經常使用字段,而同時又省去 - o 選項參數的輸入過程,那麼可使用 O 或 - O 選項。
這 2 個選項 O 或 - O,會在自定義字段以前默認增長 pid 字段,在自定義字段以後默認增長 state、tname、time 和 command 字段。
本節前面的選項都是決定輸出結果中字段的數量和順序,本小節將介紹幾個只對輸出結果中某個字段進行修飾的選項。首先來看 - w 和 w 選項。
這個實例說明,當屏幕不是很寬時,若是進程命令很長,默認狀況下,會將命令超出屏幕的部分截取掉,這樣勢必會影響系統管理員調查問題,使用 w 或 - w 選項,就會將完整的進程命令信息顯示,多出的部分換行顯示。有的時候爲了效果好一點,建議咱們能夠多使用幾回 w 選項,好比 ww、www 或 wwww。
接下來咱們再來看一下 c 和 e 選項。
選項 u 的 COMMAND 字段,默認會輸出進程路徑和執行參數信息。從上面的例子能夠看出,選項 c 可使選項 u 的 COMMAND 字段更加精簡,只保留進程名稱。選項 e 可使選項 u 的 COMMAND 字段更加豐富,增長進程環境變量的相關內容。
當選項 S 被選中,ps 命令在顯示以下 6 個字段信息時,會將已經死亡的子進程信息也包含計算在內,若是未選中 S 選項將不會計算這些已經死亡的子進程信息 。快速同時執行以下 2 個命令,便可看出這 6 個字段值,選中 S 值後比以前有明顯增大。具體字段含義請參考 8.5 小節和 8.6 小節。
Linux ps 命令的字段中有個 wchan 字段(wchan 相關含義參考 8.8 小節)。默認狀況下 ps 命令會輸出 wchan 的符號信息,若是但願輸出 wchan 的原始數值信息,可使用 n 選項。請比較以下 2 個命令,添加 n 選項先後第 11 個字段的輸出差異。除了 wchan 以外,選項 n 還能夠將本來輸出 user name 的地方轉換爲 user id 輸出。
字段 wchan 的數值信息和符號信息的映射關係經過操做系統中一些 System.map 文件完成,若是用戶須要使用自定義的 System.map 文件,能夠經過選項 N 或 - n 完成,以下示例。
前文提到 linux ps 一共最多能夠輸出 168 個字段,經過 ps L 命令可獲取詳情。經過字段相關選項能夠獲取符合用途的字段組合。爲了讓你們對 ps 命令的理解更加深刻,本節會深刻介紹一些經常使用的輸出字段的含義。
按照這些經常使用字段的內在關係,咱們將分爲如下八個小結介紹。
進程 ID 類字段是 ps 命令字段中最基礎的一類。爲了能更加形象的說明這些 ID 的關係和含義,請你們按照以下命令順序操做。
對以上輸出結果的字段逐條說明:
字段 tid 表示進程的線程 ID,能夠看出每一個線程的 tid 都不相同。
字段 nlwp 表示當前線程組中的線程個數,以上命令都是單線程進程,所以此值均爲 1。
字段 pid 表示進程 ID,也能夠看出每一個進程的 PID 都不相同。
字段 pgid 表示進程組 ID,上面的例子中除了和 setsid 結合的 vmstat 命令,其他三組經過 shell 管道鏈接起來的命令的 pgid 都相同。好比 tail、awk 和 nl 命令的 pgid 都爲 1384,且 pgid 值爲組內第一個命令 tail 的 pid 值;iostat、sed 和 fold 命令的 pgid 都爲 1388,且 pgid 值爲組內第一個命令 iostat 的 pid 值。
字段 sid 表示會話 ID。上面的例子中最後一行是第三個登陸終端的 shell。第一個登陸終端上的全部進程 sid 都相同,且爲登陸 shell 的 pid 值 1351;除了和 setsid 結合的 vmstat 命令,第二個終端上的全部進程 sid 都相同,且爲登陸 shell 的 pid 值 1394。
字段 tpgid 表示進程鏈接到的 tty(終端) 所在的前臺進程組的 ID。除了 vmstat 進程以外,第二個終端上的全部進程 tpgid 也都等於登陸 shell 的 pid 值 1394。可是第一個終端上的全部進程 tpgid 卻都等於第一個終端上又啓動的那個 shell 的進程 id 值 1370。充分說明了 tpgid 值是連接着終端的前臺進程組 ID 值。
字段 ppid 表示父進程 ID。
最後咱們再來解釋和 vmstat 結合的 setsid,setsid 就是使和它結合的 vmstat 脫離原來的會話,脫離以後 pgid 和 sid 都等於了 vmstat 進程的 pid,同時父進程也由 1 號進程託管。此時也沒有了所依附的終端,tpgid 統一等於 - 1。Linux 上的全部守護進程的 tpgid 值都是 - 1。
進程 ID 類字段的別名狀況:字段 spid 和字段 lwp 是字段 tid 的別名,字段 tgid 是字段 pid 的別名,字段 pgrp 是字段 pgid 的別名,字段 sess 和字段 session 是字段 sid 的別名。
命令名相關的字段一共有 3 組,以下所示。
命令名字段的別名狀況:字段 comm 和字段 ucomm 是字段 ucmd 的別名,字段 args 和字段 command 是字段 cmd 的別名。
建議你們掌握 ucmd 和 cmd 這 2 個字段,cmd 爲長命令名字段,ucmd 爲短命令名字段,能夠理解爲 unadorned cmd(未加修飾的命令名)。
前文提到過若是程序名稱長度超過 15 位,ps 命令的短命令名沒法完整顯示 16 位及以上的部分。下面看一個小例子來講明這個問題。
從上面的例子能夠看出,當程序名稱超過 15 位時,確實短命令名沒法顯示完整的程序名稱,只顯示了 15 位。進一步查看 / proc/8040 / 目錄,能夠發現以下信息。
查詢內核代碼,能夠發現 comm 值取自內核 struct task_struct 結構體的 comm 屬性字段。
這就告訴咱們經過 ps 命令短命令字段不管如何都沒法輸入超過 15 位的程序名稱,緣由是內核數據結構原生就只支持 15 個字符長度的程序名稱。
除此以外上面的例子還給咱們另一個啓示,若是經過使用 SYSV 風格的短命令名就能夠知足使用要求(如 ps -el),那就儘可能不要使用 BSD 風格的長命令名(如 ps -e u,即 ps aux)。長命令名須要依賴內核中健康的文件系統,而當文件系統工做不正常時,每每短命令名卻能夠不受影響。因此咱們在實際生產中偶爾會發現系統中有大量 ps aux 進程 D 住的狀況。
進程狀態類字段一共有三個,分別是 s、state 和 stat,以下所示。
字段 s 和 state 互爲別名,值爲單字節進程狀態。這裏重點介紹一下 stat 選項的多字節進程狀態,查看一下 ps 命令關於這個多字節進程狀態的 c 語言代碼。
根據以上源代碼,咱們來逐條解釋:
字符'<'表示 nice 值小於 0,nice 值最小爲 - 20。進程特性 nice 值容許進程間接的影響內核調度算法。所謂 nice 就是指對其餘進程的謙讓程度,顯然比 0 越小就越不謙讓,比 0 越大就越謙讓。顧名思義,越謙讓的君子在 CPU 調度過程當中佔用 CPU 的時間會越少,反之不謙讓的進程相比較可能佔用更多的 CPU 時間。所以字符'<'表示此進程可能在調度過程當中得到優點。
字符'N'表示 nice 值大於 0,nice 值最大爲 19。所以字符'N'表示此進程可能在調度過程當中不能得到優點。
字符'L'表示進程 vm_lock 值爲真,即此進程有內存頁被鎖在內存中,這些內存頁不能經過換頁換出。
字符's'表示進程的 tgid(pid) 值等於進程的 session(sid) 值,這說明當前進程是會話的 leader,參考 8.1 小節。
字符'l'表示進程中的線程數量大於 1,這說明當前進程是一個多線程程序。
字符'+'表示進程的 pgrp(pgid) 值等於進程的 tpgid 前臺進程組 ID,這表示當前進程在前臺進程組中。
時鐘時間(系統時間)類字段,記錄了進程開始時間點和執行的時長信息,這類字段一共有 6 組。其中 4 個記錄進程開始時間點,2 個記錄進程執行時長信息,示例以下。
從自動化運維腳本的角度,lstart 字段的輸出信息格式更加規範便於解析,etimes 字段做爲一個正整數也能夠直接使用。字段 start_time 是字段 stime 的別名。下面給一個使用的例子。
字段 lstart 的輸出固定佔用了 2 2 6 這 5 列信息,這樣在其後的 etimes 字段也固定佔用了第 $7 列。使用 awk 結合 date 命令很方便的就將進程開始時間轉化爲時間戳格式。
CPU 時間和使用率類字段一共有 5 組,記錄了進程所消耗的 CPU 時間片和 CPU 使用率信息,示例以下。
字段 bsdtime 的輸出相比較 cputime 更加方便轉換爲正整數的秒數。字段 cp 的單位是千分比,不能超過 999。字段 c 是百分比,不能超過 99。
進程 CPU 時間類字段別名:字段 atime 和字段 time 是字段 cputime 的別名;字段 util 是字段 c 的別名;字段 %cpu 是字段 pcpu 的別名,可是 % 字符在 crontab 中使用並不友好,推薦使用 pcpu。
下面來講明一下 ps 命令的 CPU 利用率的含義,先運行一個例子。
從這個命令運行的結果能夠看出 bsdtime 除以 etimes 的值轉換爲百分比後,基本和 pcpu 的值相等。這就足以說明 ps 命令的 CPU 利用率字段指標是指從進程開始運行以來進程所耗費的 CPU 時間片佔時鐘時間的百分比。有時候這個值大於 100%,那是由於進程啓用了多線程,不少時候有多核在同時使用 CPU 時間片。
看過 top 命令源碼能夠知道,top 命令默認是取最近 3 秒鐘進程所耗費的 CPU 時間片除以 3 秒鐘的百分比值。咱們能夠設想一種場景,若是一個進程已經運行了 1 年以上,平時都很穩定。可是剛剛就在十幾分鍾前忽然運行大量線程,佔用大量 CPU 資源。結果你在你剛剛登錄系統以前 10 秒鐘這些運行的線程都結束了。那麼你不管是經過 top 命令的 CPU 利用率指標,仍是 ps 命令的 CPU 利用率指標都沒法發現剛纔做怪的這個線程的跡象。
進程內存相關字段也 ps 命令字段中很是重要的一類,主要分爲以下 9 組,示例以下。
對以上輸出結果的字段逐條說明:
字段 vsz(virtual memory size)表示進程所申請的虛擬地址空間的內存大小,單位 KB。在 64 位系統中,每一個進程都有 128Tb 大小的堆內存虛擬地址空間的內存空間大小。vsz 值並不反映進程佔用的真正物理內存大小。
字段 rss(resident set size)表示進程真正佔用了的物理內存大小,單位 KB。
字段 pmem 表示進程佔用的物理內存大小 (rss) 佔本機總物理內存大小百分比。
字段 trs(text resident set size)表示用於可執行代碼的物理內存大小,約等於進程的程序尺寸大小。
字段 drs(data resident set size)表示可執行代碼以外的內存大小,實際基本等於 vsz 減去 trs 的值。
字段 size 表示若是進程交換到磁盤所需的交換空間大小。
字段 sz 表示進程在物理頁面中的核心鏡像的大小。
字段 minflt 表示此進程中發生的次缺頁異常的數量,下面詳細介紹。
字段 majflt 表示此進程中發生的主缺頁異常的數量。
進程內存相關字段別名:字段 m_drs 和字段 dsiz 是字段 drs 的別名,字段 vsize 是字段 vsz 的別名,字段 m_size 是字段 sz 的別名,字段 rssize、字段 rsz 和字段 sgi_rss 是字段 rss 的別名,字段 m_trs、字段 trss 和字段 tsiz 是字段 trs 的別名,字段 %mem 是字段 pmem 的別名,字段 min_flt 是字段 minflt 的別名,字段 maj_flt 和字段 pagein 是字段 majflt 的別名。
下面經過一個例子來加深對缺頁異常的理解。
能夠看出字段 rss 和字段 minflt 的比值趨近於 4。操做系統管理內存的基本單元是 4096 字節大小的頁框,當進程訪問還沒有有物理內存創建頁表映射關係的虛擬內存地址值時,會產生一次缺頁異常。在缺頁異常處理過程當中會爲虛擬內存頁分配一個物理內存頁並創建映射。因此每一次缺頁異常就會分配 4096(4kb)字節的物理內存,這樣 rss 和 minflt 的比值固然就是 4 了。若是分配以後又有釋放,後面再次分配,會使這個比值逐步小於 4。若是這個比值過於小,那咱們就有充足理由懷疑用戶程序代碼在內存管理上存在重大問題。
進程憑證類字段一共有 30 多個,其中大部分能夠彙總爲以下表格。
其中有些憑證是另外憑證的別名,好比 uid 是 euid 的別名,svuid 是 suid 的別名,fsuid 是 fuid 的別名。所以這些憑證字段簡單的能夠概括爲以下 4 方面憑證:
實際憑證 (real user ID):通常表示進程的建立者,屬於哪一個用戶建立。
有效憑證 (effective user ID):表示進程對於文件和資源的訪問權限,具有等同於哪一個用戶的權限。
保護憑證 (saved set-user-ID):set-user-ID 的保存 ID。
文件系統憑證 (file-system user ID):已經基本廢棄。
WCHAN 類字段一共 3 個 nwchan、wchan 和 wname。WCHAN 就是 waiting channel 的意思,進程正在休眠的內核函數的函數符號名稱。R 狀態進程此字段值爲 「-」。
字段 wchan 和 wname 都顯示的是內核函數的函數符號名稱信息,默認只顯示 6 個字節。若是但願顯示完整的函數名稱,能夠經過在字段名稱後加冒號再加寬度數值的方式顯示更豐富信息,即 wchan:25。
字段 nwchan 顯示的是內核函數符號的指針地址數值信息。一個完整的 64 位的內核函數指針地址是一個 16 位的十六進制值,前 10 位固定爲'ffffffff81',所以 ps 命令的 nwchan 字段只顯示出了後 6 位的十六進制值。好比指針地址是 ffffffff8124bb7e,那麼 nwchan 顯示 24bb7e。若是後 6 位的高位有 0,則省略掉 0 的顯示。
Linux ps 命令全部的選項和大多數字段都解釋過了,如今該說說文章開頭那個報錯的 ps -axu 了。
ps 命令會提供一種選項容錯機制。當用戶輸入的是一個 SYSV 風格參數組合後,若是參數解析失敗,ps 命令會繼續嘗試把一樣的字母組合都轉換爲 BSD 風格再嘗試進行一次解析。好比 ps -aux 解析失敗後嘗試按 ps aux 解析,ps -x 解析失敗後嘗試按 ps x 解析。固然了,若是再次按照 BSD 風格嘗試解析仍失敗,那 ps 命令會最終失敗報錯。
事實上,能有機會被 ps 命令容錯機制糾正的錯誤選項只有這 7 個,-S、-X、-h、-k、-v、-r 和 - x。由於這些字母雖然沒有 SYSV 風格的選項,可是卻都有 BSD 風格的選項。
最後說一下,沒有將 BSD 風格到 SYSV 風格的容錯機制,好比 SYSV 風格有 - F 選項,而 BSD 風格沒有 F 選項。運行命令 ps F 仍是會報錯。
本文對 linux ps 命令的 104 個短選項都進行了說明,其中只有一部分選項比較經常使用,下面根據個人經驗推薦給你們重點關注:
選項 - e:顯示全部進程的記錄,記住這個參數就能夠保證把當前系統的全部進程都輸出。須要篩選進程時,能夠結合 grep 等文本處理命令實現目的。
選項 h:選中時能夠隱藏輸出結果的標題欄信息,在一些自動化腳本中使用此參數能夠去除頁頭信息。
選項 k:經過此選項能夠實現對輸出結果的排序。
選項 - L:經過此選項能夠把多線程的進程展開每一個線程的細顆粒度。
選項 - l:或選項 l,此選項能夠列出進程的最基本信息,包括 s、pid、ppid、time 和 ucmd 等字段信息。
選項 u:此選項能夠列出 cpu 使用率、mem 使用率、rss 內存等字段信息。
選項 - o:或選項 o,經過此選項能夠自定義輸出符合本身需求的字段信息。
Linux ps 命令的 168 個輸出字段,咱們也對大部分進行了介紹。下面根據經驗推薦給你們一些經常使用的關注。