Các ví dụ về lệnh “ps” theo dõi tiến trình trên Linux Image Các ví dụ về lệnh “ps” theo dõi tiến trình trên Linux

Bài viết này giới thiệu với các bạn các ví dụ về lệnh ps theo dõi tiến trình trên hệ điều hành Linux. lệnh ps giúp chúng ta có thể liệt kê các tiến trình từ đây chúng ta có thể tự tìm hiểu và tự học Linux cơ bản dễ dàng hơn.

1. Giới thiệu lệnh ps

Lệnh ps là một trong những lệnh cơ bản nhất để xem các tiến trình đang chạy trên hệ thống. Nó cung cấp danh sách các tiến trình hiện tại cùng với các thông tin chi tiết khác như id người dùng, cách sử dụng CPU, sử dụng bộ nhớ, tên lệnh,... Cú pháp của lệnh ps như sau:

ps [option]

Để xem các option ta thực hiện lệnh: man ps

2. Sử dụng lệnh ps

👉 Ví dụ 1: Khi chúng ta thực hiện lệnh ps mà không có bất kỳ đối số nào, nó sẽ hiển thị các tiến trình trong Shell hiện tại.

[root@localhost ~]# ps
  PID TTY          TIME CMD
 1701 pts/0    00:00:00 bash
 1714 pts/0    00:00:00 ps

Chúng ta nhận được kết quả chứa bốn cột thông tin có ý nghĩa như sau:

  • PID: ID.
  • TTY: Tiến trình duy nhất, loại thiết bị đầu cuối mà người dùng đã đăng nhập vào.
  • TIME: số lượng CPU tính bằng phút và giây mà tiến trình đã chạy.
  • CMD: Tên của lệnh đã khởi chạy tiến trình.

Lưu ý: Đôi khi khi chúng ta thực thi lệnh ps nó hiển thị TIME là 00:00:00. Không có gì ngoài tổng thời gian sử dụng CPU tích lũy cho bất kỳ tiến trình nào và 00:00:00 cho thấy không có thời gian CPU nào được đưa ra bởi kernel. Trong ví dụ trên, chúng tôi thấy rằng, đối với bash không có thời gian CPU nào được đưa ra. Điều này là do bash chỉ là một tiến trình mẹ cho các tiến trình khác nhau cần bash để thực thi và bản thân bash không sử dụng bất kỳ thời gian CPU nào cho đến bây giờ.

👉 Ví dụ 2: Để hiển thị mọi tiến trình hoạt động trên hệ thống Linux ở định dạng chung (Unix/Linux) chúng ta có thể sử dụng tùy chọn -A hoặc tùy chọn -e, hai tuỳ chọn này tương đương nhau như sau:

[root@localhost ~]# ps -A
  PID TTY          TIME CMD
    1 ?        00:00:02 systemd
    2 ?        00:00:00 kthreadd
    3 ?        00:00:00 rcu_gp
    4 ?        00:00:00 rcu_par_gp
    6 ?        00:00:00 kworker/0:0H-kb
    8 ?        00:00:00 mm_percpu_wq
    9 ?        00:00:00 ksoftirqd/0
...

Hoặc

[root@localhost ~]# ps -e
  PID TTY          TIME CMD
    1 ?        00:00:02 systemd
    2 ?        00:00:00 kthreadd
    3 ?        00:00:00 rcu_gp
    4 ?        00:00:00 rcu_par_gp
    6 ?        00:00:00 kworker/0:0H-kb
    8 ?        00:00:00 mm_percpu_wq
    9 ?        00:00:00 ksoftirqd/0
...

👉 Ví dụ 3: Để hiển thị mọi tiến trình hoạt động trên hệ thống Linux ở định dạng BSD chúng ta có thể sử dụng tùy chọn au hoặc tùy chọn axu, hai tuỳ chọn này tương đương nhau như sau:

[root@localhost ~]# ps au
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      1030  0.0  0.0 110112  1836 tty1     Ss+  18:13   0:00 /sbin/agetty --noclear tty1 linux
root      1701  0.0  0.1 115448  3476 pts/0    Ss   18:30   0:00 -bash
root      1731  0.0  0.1 155368  3896 pts/0    R+   18:32   0:00 ps au

Hoặc

[root@localhost ~]# ps axu
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.1  0.3 128020  8036 ?        Ss   18:12   0:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root         2  0.0  0.0      0     0 ?        S    18:12   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        I<   18:12   0:00 [rcu_gp]
root         4  0.0  0.0      0     0 ?        I<   18:12   0:00 [rcu_par_gp]
root         6  0.0  0.0      0     0 ?        I<   18:12   0:00 [kworker/0:0H-kb]
root         8  0.0  0.0      0     0 ?        I<   18:12   0:00 [mm_percpu_wq]
root         9  0.0  0.0      0     0 ?        S    18:12   0:00 [ksoftirqd/0]
root        10  0.0  0.0      0     0 ?        R    18:12   0:00 [rcu_sched]
root        11  0.0  0.0      0     0 ?        S    18:12   0:00 [migration/0]
...

👉 Ví dụ 4: Khi chúng ta muốn hiển thị danh sách tiến trình hoạt động ở định dạng đầy đủ chúng ta có thể sử dụng tùy chọn -e kết hợp với tùy chọn F như sau:

[root@localhost ~]# ps -eF
UID        PID  PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
root         1     0  0 32005  8036   0 18:12 ?        00:00:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root         2     0  0     0     0   0 18:12 ?        00:00:00 [kthreadd]
root         3     2  0     0     0   0 18:12 ?        00:00:00 [rcu_gp]
root         4     2  0     0     0   0 18:12 ?        00:00:00 [rcu_par_gp]
root         6     2  0     0     0   0 18:12 ?        00:00:00 [kworker/0:0H-kb]
root         8     2  0     0     0   0 18:12 ?        00:00:00 [mm_percpu_wq]
root         9     2  0     0     0   0 18:12 ?        00:00:00 [ksoftirqd/0]
root        10     2  0     0     0   0 18:12 ?        00:00:00 [rcu_sched]
root        11     2  0     0     0   0 18:12 ?        00:00:00 [migration/0]
...

Hoặc chúng ta có thể sử dụng tuỳ chọn -e kết hợp tuỳ chọn f như bên dưới:

[root@localhost ~]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 18:12 ?        00:00:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root         2     0  0 18:12 ?        00:00:00 [kthreadd]
root         3     2  0 18:12 ?        00:00:00 [rcu_gp]
root         4     2  0 18:12 ?        00:00:00 [rcu_par_gp]
root         6     2  0 18:12 ?        00:00:00 [kworker/0:0H-kb]
root         8     2  0 18:12 ?        00:00:00 [mm_percpu_wq]
root         9     2  0 18:12 ?        00:00:00 [ksoftirqd/0]
root        10     2  0 18:12 ?        00:00:00 [rcu_sched]
root        11     2  0 18:12 ?        00:00:00 [migration/0]
root        13     2  0 18:12 ?        00:00:00 [cpuhp/0]
...

Hai tùy chọn F hoặc f tương đương nhau. Trong đó:

  • Tùy chọn f được sử dụng để xem danh sách định dạng đầy đủ. Nó sẽ hiển thị các trường sau: UID, PID, PPID, C, STIME, TTY, TIME CMD.

    [root@localhost ~]# ps -f
    UID        PID  PPID  C STIME TTY          TIME CMD
    root      1706  1703  0 21:05 pts/0    00:00:00 -bash
    root      1730  1706  0 21:05 pts/0    00:00:00 ps -f
    
  • Tùy chọn -F để xem thêm định dạng đầy đủ hơn tùy chọn *f. Tùy chọn này sẽ hiển thị các trường: UID, PID, PPID, C, SZ, RSS, PSR, STIME, TTY, TIME, CM.

    [root@localhost ~]# ps -F
    UID        PID  PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
    root      1706  1703  0 28860  2104   0 21:05 pts/0    00:00:00 -bash
    root      1731  1706  0 38840  1864   0 21:05 pts/0    00:00:00 ps -F
    

👉 Ví dụ 5: Chúng ta có thể xem tất cả các tiến trình do chúng ta sở hữu bằng cách chạy lệnh bên dưới:

[root@localhost ~]# ps -x
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
    2 ?        S      0:00 [kthreadd]
    3 ?        I<     0:00 [rcu_gp]
    4 ?        I<     0:00 [rcu_par_gp]
    6 ?        I<     0:00 [kworker/0:0H-kb]
    8 ?        I<     0:00 [mm_percpu_wq]
    9 ?        S      0:00 [ksoftirqd/0]
...

👉 Ví dụ 6: Để hiển thị các tiến trình của người dùng bằng tên người dùng chúng ta hãy sử dụng tùy chọn -U như sau:

[root@localhost ~]# ps -fU root
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 18:12 ?        00:00:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root         2     0  0 18:12 ?        00:00:00 [kthreadd]
root         3     2  0 18:12 ?        00:00:00 [rcu_gp]
root         4     2  0 18:12 ?        00:00:00 [rcu_par_gp]
root         6     2  0 18:12 ?        00:00:00 [kworker/0:0H-kb]
root         8     2  0 18:12 ?        00:00:00 [mm_percpu_wq]
root         9     2  0 18:12 ?        00:00:00 [ksoftirqd/0]
...

👉 Ví dụ 7: Khi chúng ta muốn in tất cả các tiến trình đang chạy dưới với quyền root (Real and Effecitve ID) ở định dạng người dùng chúng ta chạy lệnh bên dưới:

[root@localhost ~]# ps -U root -u root
  PID TTY          TIME CMD
    1 ?        00:00:02 systemd
    2 ?        00:00:00 kthreadd
    3 ?        00:00:00 rcu_gp
    4 ?        00:00:00 rcu_par_gp
    6 ?        00:00:00 kworker/0:0H-kb
    8 ?        00:00:00 mm_percpu_wq
    9 ?        00:00:00 ksoftirqd/0
...

👉 Ví dụ 8: Nếu bạn muốn liệt kê tất cả các quy trình thuộc sở hữu của một nhóm nhất định ID nhóm RGID hoặc tên thực hiện như lệnh sau:

[root@localhost ~]# ps -fG apache
UID        PID  PPID  C STIME TTY          TIME CMD
apache    2070  2069  0 18:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2071  2069  0 18:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2072  2069  0 18:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2073  2069  0 18:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2074  2069  0 18:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND

Hoặc

[root@localhost ~]# ps -fG 48
UID        PID  PPID  C STIME TTY          TIME CMD
apache    2070  2069  0 18:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2071  2069  0 18:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2072  2069  0 18:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2073  2069  0 18:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2074  2069  0 18:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND

👉 Ví dụ 9: Để liệt kê tất cả các quy trình thuộc sở hữu của tên nhóm (hoặc phiên) hiệu quả, hãy nhập.

[root@localhost ~]# ps -fg apache
UID        PID  PPID  C STIME TTY          TIME CMD
apache    2070  2069  0 18:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2071  2069  0 18:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2072  2069  0 18:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2073  2069  0 18:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2074  2069  0 18:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND

👉 Ví dụ 10: Chúng ta có thể liệt kê các tiến trình theo PID bằng cách sử dụng lệnh ps kết hợp với tùy chọn -p như sau:

[root@localhost ~]# ps -fp 1818
UID        PID  PPID  C STIME TTY          TIME CMD
root      1818  1701  0 18:41 pts/0    00:00:00 ping 8.8.8.8

👉 Ví dụ 11: Chúng ta có thể liệt kê các tiến trình theo PPID bằng cách sử dụng lệnh ps kết hợp với tùy chọn --pid như sau:

[root@localhost ~]# ps -f --pid 1821
UID        PID  PPID  C STIME TTY          TIME CMD
root      1821  1701  0 18:42 pts/0    00:00:00 ping 8.8.8.8

👉 Ví dụ 12: Chúng ta có thể hiển thị nhiều tiến trình bằng PID bằng cách viết các số PID cách nhau bởi dấu phẩy như bên dưới:

[root@localhost ~]# ps -fp 1821,2070,1853
UID        PID  PPID  C STIME TTY          TIME CMD
root      1821  1701  0 18:42 pts/0    00:00:00 ping 8.8.8.8
root      1853  1701  0 18:46 pts/0    00:00:00 ping 8.8.8.8
apache    2070  2069  0 18:50 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND

👉 Ví dụ 13: Để có thể hiển thị các tiến trình theo TTY chúng ta sử dụng tùy chọn -t như bên dưới:

[root@localhost ~]# ps -t pts/0
  PID TTY          TIME CMD
 1701 pts/0    00:00:00 bash
 1818 pts/0    00:00:00 ping
 1821 pts/0    00:00:00 ping
 1826 pts/0    00:00:00 ping
 1853 pts/0    00:00:00 ping
 2259 pts/0    00:00:00 ps
[root@localhost ~]# ps -t tty1
  PID TTY          TIME CMD
 1030 tty1     00:00:00 agetty

👉 Ví dụ 14: Khi chúng ta muốn xem cây các tiến trình để thấy các tiến trình trên hệ thống được liên kết với nhau như thế nào chúng ta thực hiện lệnh như sau:

[root@localhost ~]# ps -e --forest
  PID TTY          TIME CMD
    2 ?        00:00:00 kthreadd
    3 ?        00:00:00  \_ rcu_gp
    4 ?        00:00:00  \_ rcu_par_gp
    6 ?        00:00:00  \_ kworker/0:0H-kb
    8 ?        00:00:00  \_ mm_percpu_wq
    9 ?        00:00:00  \_ ksoftirqd/0
   10 ?        00:00:00  \_ rcu_sched
   11 ?        00:00:00  \_ migration/0
...

👉 Ví dụ 15: Để có thể in cây tiến trình cho một tiến trình nhất định chúng ta thực hiện như bên dưới:

[root@localhost ~]# ps -f --forest -C sshd
UID        PID  PPID  C STIME TTY          TIME CMD
root      1452     1  0 18:13 ?        00:00:00 /usr/sbin/sshd -D
root      1698  1452  0 18:30 ?        00:00:00  \_ sshd: root@pts/0
[root@localhost ~]# ps -ef --forest | grep -v grep | grep sshd
root      1452     1  0 18:13 ?        00:00:00 /usr/sbin/sshd -D
root      1698  1452  0 18:30 ?        00:00:00  \_ sshd: root@pts/0

👉 Ví dụ 16: Để in tất cả các luồng của một tiến trình chúng ta sử dụng tùy chọn -L sẽ hiển thị các cột LWP (tiến trình trọng lượng nhẹ) cũng như các cột NLWP (số lượng tiến trình trình trọng lượng nhẹ).

[root@localhost ~]# ps -fL -C  sshd
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root      1452     1  1452  0    1 18:13 ?        00:00:00 /usr/sbin/sshd -D
root      1698  1452  1698  0    1 18:30 ?        00:00:00 sshd: root@pts/0

👉 Ví dụ 17: Chúng ta sử dụng tuỳ chọn -o hoặc tùy chọn -format để có thể hiển thị định dạng đầu ra theo ý muốn. Lệnh bên dưới cho phép chúng ta xem PID, PPID, user name, command của một tiến trình:

[root@localhost ~]# ps -eo pid,ppid,user,tty,cmd
  PID  PPID USER     TT       CMD
    1     0 root     ?        /usr/lib/systemd/systemd --switched-root --system --deserialize 22
    2     0 root     ?        [kthreadd]
    3     2 root     ?        [rcu_gp]
    4     2 root     ?        [rcu_par_gp]
    6     2 root     ?        [kworker/0:0H-kb]
    8     2 root     ?        [mm_percpu_wq]
    9     2 root     ?        [ksoftirqd/0]
   10     2 root     ?        [rcu_sched]

👉 Ví dụ 18: Chúng ta sử dụng tuỳ chọn -o hoặc tùy chọn -format để có thể hiển thị định dạng đầu ra theo ý muốn. Lệnh bên dưới là một ví dụ định dạng đầu ra gồm có system group, nice value, start time, elapsed, time của một tiến trình.

[root@localhost ~]#  ps -p 2195 -o pid,ppid,fgroup,ni,lstart,etime
  PID  PPID FGROUP    NI                  STARTED     ELAPSED
 2195     1 root       0 Fri Jul 26 19:01:02 2019       19:26

👉 Ví dụ 19: Để tìm tên tiến trình bằng cách sử dụng PID chúng ta thực hiện như bên dưới:

[root@localhost ~]# ps -p 1818 -o comm=
ping

👉 Ví dụ 20: Để có thể chọn một tiến trình cụ thể theo tên của nó chúng ta sử dụng tùy chọn -C tùy chọn này sẽ hiển thị tất cả các tiến trình con của nó:

[root@localhost ~]# ps -C httpd
  PID TTY          TIME CMD
 2069 ?        00:00:00 httpd
 2070 ?        00:00:00 httpd
 2071 ?        00:00:00 httpd
 2072 ?        00:00:00 httpd
 2073 ?        00:00:00 httpd
 2074 ?        00:00:00 httpd

👉 Ví dụ 21: Tìm tất cả các PID từ tên của một tiến trình chúng ta có thể thực hiện như sau:

[root@localhost ~]# ps -C ping -o pid=
 1818
 1821
 1826
 1853

👉 Ví dụ 22: Khi chúng ta muốn kiểm tra thời gian thực hiện của một tiến trình chúng ta sử dụng tuỳ chọn -o hoặc tùy chọn -format để có thể hiển thị định dạng đầu ra gồm có etime như bên dưới:

[root@localhost ~]# ps -eo comm,etime,user | grep sshd
sshd               01:09:54 root
sshd                  52:51 root

👉 Ví dụ 23: Tìm các tiến trình chạy hàng đầu theo mức sử dụng bộ nhớ và CPU cao nhất trong Linux, kết hợp lệnh head để có thể lọc lấy 10 tiến trình sử dụng bộ nhớ và CPU cao nhất thực hiện như sau:

[root@localhost ~]# ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head
  PID  PPID CMD                         %MEM %CPU
 1033     1 /usr/bin/python -Es /usr/sb  1.9  0.0
 1453     1 /usr/bin/python2 -Es /usr/s  1.0  0.0
  991     1 /usr/lib/polkit-1/polkitd -  0.8  0.0
 1069     1 /usr/sbin/NetworkManager --  0.6  0.0
 1014     1 /usr/bin/vmtoolsd            0.5  0.0
 1013     1 /usr/bin/VGAuthService -s    0.5  0.0
 1698  1452 sshd: root@pts/0             0.4  0.0
    1     0 /usr/lib/systemd/systemd --  0.4  0.0
 1452     1 /usr/sbin/sshd -D            0.3  0.0
[root@localhost ~]# ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu | head
  PID  PPID CMD                         %MEM %CPU
    1     0 /usr/lib/systemd/systemd --  0.4  0.0
    2     0 [kthreadd]                   0.0  0.0
    3     2 [rcu_gp]                     0.0  0.0
    4     2 [rcu_par_gp]                 0.0  0.0
    6     2 [kworker/0:0H-kb]            0.0  0.0
    8     2 [mm_percpu_wq]               0.0  0.0
    9     2 [ksoftirqd/0]                0.0  0.0
   10     2 [rcu_sched]                  0.0  0.0
   11     2 [migration/0]                0.0  0.0

👉 Ví dụ 24: Để hiển thị bối cảnh bảo mật (cụ thể cho SELinux) chúng ta thực thi lệnh bên dưới:

[root@localhost ~]# ps -eM
LABEL                             PID TTY          TIME CMD
system_u:system_r:init_t:s0         1 ?        00:00:02 systemd
system_u:system_r:kernel_t:s0       2 ?        00:00:00 kthreadd
system_u:system_r:kernel_t:s0       3 ?        00:00:00 rcu_gp
system_u:system_r:kernel_t:s0       4 ?        00:00:00 rcu_par_gp
system_u:system_r:kernel_t:s0       6 ?        00:00:00 kworker/0:0H-kb
system_u:system_r:kernel_t:s0       8 ?        00:00:00 mm_percpu_wq
...

Hoặc chúng ta có thể thực hiện lệnh sau, lệnh bên dưới này cũng tương đương lệnh trên:

[root@localhost ~]# ps --context
  PID CONTEXT                         COMMAND
 1701 unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 -bash
 1818 unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 ping 8.8.8.8
 1821 unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 ping 8.8.8.8
 1826 unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 ping 8.8.8.8
 1853 unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 ping 8.8.8.8
 2419 unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 ps --context

👉 Ví dụ 25: Bạn cũng có thể hiển thị thông tin bảo mật ở định dạng do người dùng xác định bằng lệnh này:

[root@localhost ~]# ps -eo  euser,ruser,suser,fuser,f,comm,label
EUSER    RUSER    SUSER    FUSER    F COMMAND         LABEL
root     root     root     root     4 systemd         system_u:system_r:init_t:s0
root     root     root     root     1 kthreadd        system_u:system_r:kernel_t:s0
root     root     root     root     1 rcu_gp          system_u:system_r:kernel_t:s0
root     root     root     root     1 rcu_par_gp      system_u:system_r:kernel_t:s0
root     root     root     root     1 kworker/0:0H-kb system_u:system_r:kernel_t:s0
root     root     root     root     1 mm_percpu_wq    system_u:system_r:kernel_t:s0
root     root     root     root     1 ksoftirqd/0     system_u:system_r:kernel_t:s0
...

👉 Ví dụ 26: Vì lệnh ps hiển thị thông tin tĩnh, bạn có thể sử dụng tiện ích đồng hồ để thực hiện giám sát quy trình thời gian thực với đầu ra lặp đi lặp lại, được hiển thị sau mỗi giây như trong lệnh bên dưới:

[root@localhost ~]# watch -n 1 'ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head'

Every 1.0s: ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head                                                      Fri Jul 26 19:28:24 2019

  PID  PPID CMD                         %MEM %CPU
 1033     1 /usr/bin/python -Es /usr/sb  1.9  0.0
 1453     1 /usr/bin/python2 -Es /usr/s  1.0  0.0
  991     1 /usr/lib/polkit-1/polkitd -  0.8  0.0
 1069     1 /usr/sbin/NetworkManager --  0.6  0.0
 1014     1 /usr/bin/vmtoolsd            0.5  0.0
 1013     1 /usr/bin/VGAuthService -s    0.5  0.0
 1698  1452 sshd: root@pts/0             0.4  0.0
    1     0 /usr/lib/systemd/systemd --  0.4  0.0
 1452     1 /usr/sbin/sshd -D            0.3  0.0

3. Giới thiệu lệnh pstree

Lệnh pstree là một lệnh hữu ích để hiển thị các tiến trình đang chạy trong Linux. Giống như lệnh ps nó hiển thị tất cả các tiến trình đang chạy trên hệ thống của bạn. Sự khác biệt chính là các tiến trình được tổ chức trong một cây thay vì trong một danh sách. Cây này cho thấy các quá trình trong mối quan hệ mẹ-con. Tiến trình mẹ là tiến trình sinh sản, tạo ra tất cả các tiến trình con bên dưới nó.

Cú pháp của lệnh pstree có dạng như sau:

pstree [option]

Để xem các option ta thực hiện lệnh: man pstree

4. Sử dụng lệnh pstree

👉 Ví dụ 1: Khi chúng ta thực hiện lệnh pstree mà không có bất kỳ đối số nào, nó sẽ hiển thị các tiến trình hiện tại:

[root@localhost ~]# pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]
        ├─VGAuthService
        ├─agetty
        ├─anacron
        ├─auditd───{auditd}
        ├─crond
        ├─dbus-daemon───{dbus-daemon}
        ├─firewalld───{firewalld}
        ├─gssproxy───5*[{gssproxy}]
        ├─httpd───5*[httpd]
        ├─lvmetad
        ├─master─┬─pickup
        │        └─qmgr
        ├─polkitd───6*[{polkitd}]
        ├─rpcbind
        ├─rsyslogd───2*[{rsyslogd}]
        ├─sshd───sshd───bash─┬─4*[ping]
        │                    └─pstree
        ├─systemd-journal
        ├─systemd-logind
        ├─systemd-udevd
        ├─tuned───4*[{tuned}]
        └─vmtoolsd───{vmtoolsd}

Lệnh này sẽ hiển thị một danh sách tất cả các tiến trình đang chạy. Tiến trình ở trên cùng là systemd là tiến trình mẹ cho mọi thứ chạy trên máy của chúng ta. Các tiến trình bên dưới nó được sinh ra hoặc mở thông qua systemd. Các lớp thụt tiếp theo cho thấy các mối quan hệ tương tự.

Cấu trúc cơ bản của lệnh pstree có dạng như sau:

parent————child(1)————subchild (1)
        |          |--subchild (2)
        |
        |-child(2)

👉 Ví dụ 2: Khi chúng ta muốn hiển thị các đối số dòng lệnh trong đầu ra bằng lệnh pstree thì chúng ta sẽ kết hợp nó với tuỳ chọn -a:

[root@localhost ~]# pstree -a
systemd --switched-root --system --deserialize 22
  ├─NetworkManager --no-daemon
  │   └─2*[{NetworkManager}]
  ├─VGAuthService -s
  ├─agetty --noclear tty1 linux
  ├─anacron -s
  ├─auditd
  │   └─{auditd}
  ├─crond -n
  ├─dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
  │   └─{dbus-daemon}
  ├─firewalld -Es /usr/sbin/firewalld --nofork --nopid
  │   └─{firewalld}
  ├─gssproxy -D
  │   └─5*[{gssproxy}]
  ├─httpd -DFOREGROUND
  │   ├─httpd -DFOREGROUND
  │   ├─httpd -DFOREGROUND
  │   ├─httpd -DFOREGROUND
  │   ├─httpd -DFOREGROUND
  │   └─httpd -DFOREGROUND
  ├─lvmetad -f
  ├─master -w
  │   ├─pickup -l -t unix -u
  │   └─qmgr -l -t unix -u
  ├─polkitd --no-debug
  │   └─6*[{polkitd}]
  ├─rpcbind -w
  ├─rsyslogd -n
  │   └─2*[{rsyslogd}]
  ├─sshd -D
  │   └─sshd
  │       └─bash
  │           ├─ping 8.8.8.8
  │           ├─ping 8.8.8.8
  │           ├─ping 8.8.8.8
  │           ├─ping 8.8.8.8
  │           └─pstree -a
  ├─systemd-journal
  ├─systemd-logind
  ├─systemd-udevd
  ├─tuned -Es /usr/sbin/tuned -l -P
  │   └─4*[{tuned}]
  └─vmtoolsd
      └─{vmtoolsd}

👉 Ví dụ 3: Để hiển thị thông tin nhận dạng tiến trình, chúng ta có thể sử dụng tuỳ chọn -p hiển thị số nhận dạng tiến trình hoặc PID như sau:

[root@localhost ~]# pstree -p
systemd(1)─┬─NetworkManager(1069)─┬─{NetworkManager}(1080)
           │                      └─{NetworkManager}(1082)
           ├─VGAuthService(1013)
           ├─agetty(1030)
           ├─anacron(2195)
           ├─auditd(970)───{auditd}(971)
           ├─crond(1024)
           ├─dbus-daemon(997)───{dbus-daemon}(1011)
           ├─firewalld(1033)───{firewalld}(1241)
           ├─gssproxy(1004)─┬─{gssproxy}(1006)
           │                ├─{gssproxy}(1007)
           │                ├─{gssproxy}(1008)
           │                ├─{gssproxy}(1009)
           │                └─{gssproxy}(1010)
           ├─httpd(2069)─┬─httpd(2070)
           │             ├─httpd(2071)
           │             ├─httpd(2072)
           │             ├─httpd(2073)
           │             └─httpd(2074)
           ├─lvmetad(777)
           ├─master(1561)─┬─pickup(1562)
           │              └─qmgr(1564)
           ├─polkitd(991)─┬─{polkitd}(1015)
           │              ├─{polkitd}(1016)
           │              ├─{polkitd}(1017)
           │              ├─{polkitd}(1022)
           │              ├─{polkitd}(1026)
           │              └─{polkitd}(1031)
           ├─rpcbind(999)
           ├─rsyslogd(1456)─┬─{rsyslogd}(1463)
           │                └─{rsyslogd}(1464)
           ├─sshd(1452)───sshd(1698)───bash(1701)─┬─ping(1818)
           │                                      ├─ping(1821)
           │                                      ├─ping(1826)
           │                                      ├─ping(1853)
           │                                      └─pstree(2477)
           ├─systemd-journal(745)
           ├─systemd-logind(990)
           ├─systemd-udevd(782)
           ├─tuned(1453)─┬─{tuned}(1504)
           │             ├─{tuned}(1505)
           │             ├─{tuned}(1506)
           │             └─{tuned}(1521)
           └─vmtoolsd(1014)───{vmtoolsd}(1038)

👉 Ví dụ 4: Trong trường hợp chúng ta muốn làm nổi bật một tiến trình cụ thể ở đầu ra hãy sử dụng tùy chọn -H. Cú pháp như sau:

pstree -H [PID]

Trong đó PID là ID của quá trình bạn muốn làm nổi bật. Ví dụ, chúng ta muốn đánh dấu quá trình httpd trên hệ thống của bằng cách thực thi lệnh sau:

[root@localhost ~]# pstree -H 2070
systemd─┬─NetworkManager─┬─dhclient
        │                └─2*[{NetworkManager}]
        ├─VGAuthService
        ├─agetty
        ├─anacron
        ├─auditd───{auditd}
        ├─crond
        ├─dbus-daemon───{dbus-daemon}
        ├─firewalld───{firewalld}
        ├─gssproxy───5*[{gssproxy}]
        ├─httpd───5*[httpd]
        ├─lvmetad
        ├─master─┬─pickup
        │        └─qmgr
        ├─polkitd───6*[{polkitd}]
        ├─rpcbind
        ├─rsyslogd───2*[{rsyslogd}]
        ├─sshd───sshd───bash─┬─4*[ping]
        │                    └─pstree
        ├─systemd-journal
        ├─systemd-logind
        ├─systemd-udevd
        ├─tuned───4*[{tuned}]
        └─vmtoolsd───{vmtoolsd}

👉 Ví dụ 5: Để lệnh pstree có thể hiển thị ID của nhóm tiến trình trong đầu ra chúng ta sử dụng tùy chọn -g:

[root@localhost ~]# pstree -g
systemd(1)─┬─NetworkManager(1069)─┬─dhclient(2778)
           │                      ├─{NetworkManager}(1069)
           │                      ├─{NetworkManager}(1069)
           │                      └─{NetworkManager}(1069)
           ├─VGAuthService(1013)
           ├─agetty(1030)
           ├─anacron(2195)
           ├─auditd(970)───{auditd}(970)
           ├─crond(1024)
           ├─dbus-daemon(997)───{dbus-daemon}(997)
           ├─firewalld(1033)───{firewalld}(1033)
           ├─gssproxy(1004)─┬─{gssproxy}(1004)
           │                ├─{gssproxy}(1004)
           │                ├─{gssproxy}(1004)
           │                ├─{gssproxy}(1004)
           │                └─{gssproxy}(1004)
           ├─httpd(2069)─┬─httpd(2069)
           │             ├─httpd(2069)
           │             ├─httpd(2069)
           │             ├─httpd(2069)
           │             └─httpd(2069)
           ├─lvmetad(777)
           ├─master(1561)─┬─pickup(1561)
           │              └─qmgr(1561)
           ├─polkitd(991)─┬─{polkitd}(991)
           │              ├─{polkitd}(991)
           │              ├─{polkitd}(991)
           │              ├─{polkitd}(991)
           │              ├─{polkitd}(991)
           │              └─{polkitd}(991)
           ├─rpcbind(999)
           ├─rsyslogd(1456)─┬─{rsyslogd}(1456)
           │                └─{rsyslogd}(1456)
           ├─sshd(1452)───sshd(1698)───bash(1701)─┬─ping(1818)
           │                                      ├─ping(1821)
           │                                      ├─ping(1826)
           │                                      ├─ping(1853)
           │                                      └─pstree(2784)
           ├─systemd-journal(745)
           ├─systemd-logind(990)
           ├─systemd-udevd(782)
           ├─tuned(1453)─┬─{tuned}(1453)
           │             ├─{tuned}(1453)
           │             ├─{tuned}(1453)
           │             └─{tuned}(1453)
           └─vmtoolsd(1014)───{vmtoolsd}(1014)

👉 Ví dụ 6: Chúng ta có thể hiển thị các bộ phận của cây của một tiến trình cụ thể bằng PID bằng cách sử dụng tùy chọn -s, tuỳ chọn này giúp chúng ta nhìn thấy tiến trình mẹ đến tiến trình con mà chúng ta đã chỉ định:

[root@localhost ~]# pstree -s 1853
systemd───sshd───sshd───bash───ping

5. Cách xác định các tiến trình đang chờ I/O trên đĩa

Trong hệ điều hành Linux thì một tiến trình có thể ở một số trạng thái. Chúng ta cùng xem lại các mã trạng thái tiến trình như sau:

PROCESS STATE CODES
       Here are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe the state of a process.
       D    Uninterruptible sleep (usually IO)
       R    Running or runnable (on run queue)
       S    Interruptible sleep (waiting for an event to complete)
       T    Stopped, either by a job control signal or because it is being traced.
       W    paging (not valid since the 2.6.xx kernel)
       X    dead (should never be seen)
       Z    Defunct ("zombie") process, terminated but not reaped by its parent.

       For BSD formats and when the stat keyword is used, additional characters may be displayed:
       <    high-priority (not nice to other users)
       N    low-priority (nice to other users)
       L    has pages locked into memory (for real-time and custom IO)
       s    is a session leader
       l    is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
       +    is in the foreground process group

Một tiến trình bắt đầu ở trạng thái R và kết thúc ở trạng thái Z (zombie) như bên dưới:

Tiến trình bắt đầu ở trạng thái R

👉 Ví dụ: Sử dụng lệnh ps kết hợp với lệnh awk để xác định các tiến trình ở trạng thái 'D: Uninterruptible sleep (usually IO)' như sau:

[root@localhost ~]# ps aux | awk '$8 ~ /D/  { print $0 }'
root       473  0.1  0.0      0     0 ?        D    11:48   0:10 [kworker/u2:29]
root       563  0.0  0.0      0     0 ?        D    11:48   0:01 [xfsaild/dm-0]
root      5706  2.0  0.0 121136  1300 tty1     D+   14:29   0:01 cp -i -av FILE ISO/ /opt/

6. Lời kết

Qua bài trên, giúp cho chúng ta biết cách sử dụng lệnh ps theo dõi tiến trình trên hệ điều hành Linux. Đồng thời qua các ví dụ bên trên cũng giúp chúng ta biết cách sử dụng lệnh ps cùng với lệnh pstree chi tiết hơn từ đây giúp chúng ta có thể theo dõi và quản lý hệ thống một cách an toàn và hiệu quả nhất.