這才是使用ps命令的正確姿勢

這才是使用ps命令的正確姿勢

前言

在linux系統當中我們通常會使用命令去查看一些系統的進程信息,我們最常使用的就是 ps (process status)。ps 命令主要是用於查看當前正在運行的程序,以及他們相關的的信息,我們可以通過不同的選項進行查看。ps 給我們提供了非常多的選項,這些選項常常令人分辨不清楚,本篇文章我們仔細談一談 ps 輸出具體的含義。

ps命令詳解

只輸出跟當前shell有關的進程

當我們在命令行當中直接輸入 ps 命令,那麼就只能夠看到在當前終端當中啟動的進程,即使同一個用戶啟動其他的終端,在這個終端當中也不能看到同一個用戶在其他終端啟動的進程,如下圖所示:

分割線表示上下有兩個終端:

  • 我們在上一個終端後台啟動一個 sleep.out 的程序,我們就能夠在上面的終端裏面看到我們剛剛啟動的程序。
  • 但是我們在下面同一個用戶的不同終端就不能夠看到在上面一個終端啟動的程序。

ps 命令輸出的含義:

  • PID:進程的進程號,有唯一性。
  • TTY:用戶登陸的時候使用的虛擬終端。
  • TIME:程序使用的CPU時間總和。
  • CMD:進程啟動的時候執行的命令。

輸出所有的進程

ps -A
ps -e

上面的兩個命令輸出系統當中所有的進程信息,我們可以使用這個命令統計系統當中一個有多少進程:

輸出所有進程但是排除終端和session leader

ps -a

上面的命令輸出除了 session leader 和跟終端無關的所有進程。

  • 跟終端無關的進程很好理解,就是跟終端脫離關係,一般是系統進程和用戶的守護進程。
  • 而 session leader 就是你登陸終端時候的那個進程,如下圖所示:

一個更具體的描述一個 shell 中 session leader 和其他進程的關係如下圖所示(圖中最左方就是 session leader 進程):

查看正在運行的程序

ps -r

查看當前用戶的進程

ps -x

查看具體某個進程的信息

ps -p pid

輸出內容攜帶用戶名

ps -u

查看所有與當前終端有關的進程

這個命令和直接輸入ps執行的效果一樣

ps -T

一個我們非常熟悉的命令

我們在linux操作系統下面我們通常使用 ps 命令的時候,我們會使用如下兩個命令:

ps aux # ax 通常要在一起使用 一起使用時候的效果和 -e 或者 -A 是一樣的
ps -ef

其實在很多情況下我們只想查看與我們自己有關的程序,而上面的兩個命令還查看了很多其他用戶的進程,因此我們可以修改一下上面兩個命令:

ps xu

上面這個命令只會輸出與我們自己有關的程序同時輸出的內容還算完整。

指定ps命令輸出的內容

在前面的命令當中我們都沒有定製化的輸出過一些內容,都是ps命令想輸出啥就輸出啥!其實我們可以指定ps命令只輸出我們需要的內容,比如下面的命令輸出進程id,父進程id,以及程序執行時候輸入的命令:

ps -o pid,ppid,command
➜  pthreads ps -o pid,ppid,command
    PID    PPID COMMAND
2782266   34624 /usr/bin/zsh
2825942 2782266 ps -o pid,ppid,command

-o表示指定我們想要輸出的內容,在上面的命令當中:

  • pid: 表示當前進程的進程號。
  • ppid: 表示當前進程父進程的進程號。
  • command: 表示執行這個命令的時候輸入的命令。

還有很多其他的可以輸出的內容,在下表當中列出一些經常使用的條目:

條目 含義
pid 進程號
ppid 父進程進程號
command 執行命令
%cpu 進程對於cpu的使用率
%mem 內存佔有率
comm 更加簡潔的命令和command一致
cputime 進程累計使用的CPU時間
etime 進程開始執行到現在一共過了多長時間
stat 進程的狀態
ni 進程的優先級
user 用戶名

這裡我們在重點談一下進程的狀態 stat,我們看一個他的輸出:

➜  pthreads ps -o pid,ppid,stat,command
    PID    PPID STAT COMMAND
2782266   34624 Ss   /usr/bin/zsh
2832729 2782266 SN   ./sleep.out
2832740 2782266 R+   ps -o pid,ppid,stat,command

在上面當中 STAT 那一列就是表示進程的狀態,我們現在仔細分析一下上面字母表示的含義:

STAT 當中字母的含義表:

條目 含義
D 表示不能夠被中斷的睡眠操作,比如說IO操作
I 內核當中的空閑線程
R 正在執行或者處於就緒隊列當中的進程
S 可以被中斷的睡眠,一般是等待某個事件觸發
T 被其他的進程發送的信號給停下來了
t 被調試或者tracing中
Z 表示這個進程是一個殭屍進程
< 表示高優先級
N 表示低優先級
L 有頁面被所在內存當中,也就是說這個頁面不會被操作系統換出道對換區當中
s 表示這個進程是一個 session leader
l 是一個多線程程序
+ 表示在前台進程組當中

現在根據上面表格當中的內容我們可以知道:

  • 進程 2782266 正在等待某個事件觸發,而且這個進程是 session leader。
  • 進程 2832729 也是在等待某個事件觸發,而且是低優先級的進程。
  • 進程 2832740 正在執行。

下圖表示 linux 當中進程的幾種狀態:

我們在來看一個多進程程序的例子:


#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

void* func(void* args) {
  while (1)
  {
    /* code */
  }
  
}
int main() {
  for(int i = 0; i < 10; i++) {
    pthread_t tid;
    pthread_create(&tid, NULL, func, NULL);
  }
  while (1)
  {
    sleep(1);
  }
  
  return 0;
}

上面的程序執行完成之後,ps 的輸出結果如下:

➜  pthreads ps -o pid,ppid,stat,command
    PID    PPID STAT COMMAND
2782266   34624 Ss   /usr/bin/zsh
2840012 2782266 SNl  ./sleep.out # 這個進程就是上面那個程序表示的進程
2840037 2782266 R+   ps -o pid,ppid,stat,command

我們可以看到這個進程的 STAT 當中還有一個 l 表示這是一個多進程的程序。

總結

在本篇文章當中主要給大家介紹了一些常見的 ps 命令的使用方法,以及一些常用的輸出,還有就是輸出內容中比較重要的進程狀態,能夠很好的幫助我們實時去了解進程。


以上就是本篇文章的所有內容了,我是LeHung,我們下期再見!!!更多精彩內容合集可訪問項目://github.com/Chang-LeHung/CSCore

關注公眾號:一無是處的研究僧,了解更多計算機(Java、Python、計算機系統基礎、算法與數據結構)知識。