Linux Shell常用技巧(九) 系統運行進程

Linux Shell常用技巧(九) 系統運行進程

十九.  和系統運行進程相關的Shell命令:
    
   1.  進程監控命令(ps):
      要對進程進行監測和控制,首先必須要了解當前進程的情況,也就是需要查看當前進程,而ps命令就是最基本同時也是非常強大的進程查看命令。使用該命令可以 確定有哪些進程正在運行和運行的狀態、進程是否結束、進程有沒有僵死、哪些進程佔用了過多的資源等等。總之大部分信息都是可以通過執行該命令得到的。
    ps命令存在很多的命令行選項和參數,然而我們最爲常用只有兩種形式,這裏先給出與它們相關的選項和參數的含義:

選項說明
a顯示終端上的所有進程,包括其他用戶的進程。
u以用戶爲主的格式來顯示程序狀況。
x顯示所有程序,不以終端來區分。
-e顯示所有進程。
o其後指定要輸出的列,如user,pid等,多個列之間用逗號分隔。
-p後面跟着一組pid的列表,用逗號分隔,該命令將只是輸出這些pid的相關數據。

    /> ps aux

    root         1  0.0  0.1   2828  1400 ?        Ss   09:51   0:02 /sbin/init
    root         2  0.0  0.0      0          0 ?        S    09:51   0:00 [kthreadd]
    root         3  0.0  0.0      0          0 ?        S    09:51   0:00 [migration/0]
    ... ...  
    /> ps -eo user,pid,%cpu,%mem,start,time,command | head -n 4
    USER       PID %CPU %MEM  STARTED     TIME        COMMAND
    root         1         0.0    0.1   09:51:08     00:00:02  /sbin/init
    root         2         0.0    0.0   09:51:08     00:00:00  [kthreadd]
    root         3         0.0    0.0   09:51:08     00:00:00  [migration/0]
    這裏需要說明的是,ps中存在很多和進程性能相關的參數,它們均以輸出表格中的列的方式顯示出來,在這裏我們只是給出了非常常用的幾個參數,至於更多參數,我們則需要根據自己應用的實際情況去看ps的man手冊。
    #以完整的格式顯示pid爲1(init)的進程的相關數據
    /> ps -fp 1
    UID        PID  PPID  C STIME TTY          TIME   CMD
    root         1        0  0 05:16   ?        00:00:03 /sbin/init
   
    2.  改變進程優先級的命令(nice和renice):
    該Shell命令最常用的使用方式爲:nice [-n <優先等級>][執行指令],其中優先等級的範圍從-20-19,其中-20最高,19最低,只有系統管理者可以設置負數的等級。
    #後臺執行sleep 100秒,同時在啓動時將其nice值置爲19
    /> nice -n 19 sleep 100 &
    [1] 4661
    #後臺執行sleep 100秒,同時在啓動時將其nice值置爲-19
    /> nice -n -19 sleep 100 &
    [2] 4664
    #關注ps -l輸出中用黃色高亮的兩行,它們的NI值和我們執行是設置的值一致。
    /> ps -l
    F S   UID   PID  PPID  C PRI  NI  ADDR  SZ    WCHAN  TTY       TIME        CMD
    4 S     0  2833  2829  0  80   0     -      1739     -         pts/2    00:00:00  bash
    0 S     0  4661  2833  0  99  19    -      1066     -         pts/2    00:00:00  sleep
    4 S     0  4664  2833  0  61 -19    -      1066     -         pts/2    00:00:00  sleep
    4 R     0  4665  2833  1  80   0     -      1231     -         pts/2    00:00:00  ps
   
    renice命令主要用於爲已經執行的進程重新設定nice值,該命令包含以下幾個常用選項:

選項說明
-g使用程序羣組名稱,修改所有隸屬於該程序羣組的程序的優先權。
-p改變該程序的優先權等級,此參數爲預設值。
-u指定用戶名稱,修改所有隸屬於該用戶的程序的優先權。

    #切換到stephen用戶下執行一個後臺進程,這裏sleep進程將在後臺睡眠1000秒。
    /> su stephen
    /> sleep 1000&  
    [1] 4812
    /> exit   #退回到切換前的root用戶
    #查看已經啓動的後臺sleep進程,其ni值爲0,宿主用戶爲stephen
    /> ps -eo user,pid,ni,command | grep stephen
    stephen   4812   0 sleep 1000
    root        4821    0 grep  stephen
    #以指定用戶的方式修改該用戶下所有進程的nice值
    /> renice -n 5 -u stephen
    500: old priority 0, new priority 5
    #從再次執行ps的輸出結果可以看出,該sleep後臺進程的nice值已經調成了5
    /> ps -eo user,pid,ni,command | grep stephen
    stephen   4812   5 sleep 1000
    root         4826   0 grep  stephen
    #以指定進程pid的方式修改該進程的nice值
    /> renice -n 10 -p 4812
    4812: old priority 5, new priority 10
    #再次執行ps,該sleep後臺進程的nice值已經從5變成了10
    /> ps -eo user,pid,ni,command | grep stephen
    stephen   4812  10 sleep 1000
    root        4829   0 grep  stephen


    3.  列出當前系統打開文件的工具(lsof):
    lsof(list opened files),其重要功能爲列舉系統中已經被打開的文件,如果沒有指定任何選項或參數,lsof則列出所有活動進程打開的所有文件衆所周知,linux環境中任何事物都是文件,如設備、目錄、sockets等。所以,用好lsof命令,對日常的linux管理非常有幫助。下面先給出該命令的常用選項:

選項說明
-a該選項會使後面選項選出的結果列表進行and操作。
-c command_prefix顯示以command_prefix開頭的進程打開的文件。
-p PID顯示指定PID已打開文件的信息
+d directory從文件夾directory來搜尋(不考慮子目錄),列出該目錄下打開的文件信息。
+D directory從文件夾directory來搜尋(考慮子目錄),列出該目錄下打開的文件信息。
-d num_of_fd以File Descriptor的信息進行匹配,可使用3-10,表示範圍,3,10表示某些值。
-u user顯示某用戶的已經打開的文件,其中user可以使用正則表達式。
-i監聽指定的協議、端口、主機等的網絡信息,格式爲:[proto][@host|addr][:svc_list|port_list]

    #查看打開/dev/null文件的進程。
    /> lsof /dev/null | head -n 5
    COMMAND    PID      USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    init         1      root    0u   CHR    1,3      0t0 3671 /dev/null
    init         1      root    1u   CHR    1,3      0t0 3671 /dev/null
    init         1      root    2u   CHR    1,3      0t0 3671 /dev/null
    udevd 397      root    0u   CHR    1,3      0t0 3671 /dev/null

    #查看打開22端口的進程
    /> lsof -i:22
    COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    sshd    1582 root    3u  IPv4  11989      0t0  TCP *:ssh (LISTEN)
    sshd    1582 root    4u  IPv6  11991      0t0  TCP *:ssh (LISTEN)
    sshd    2829 root    3r   IPv4  19635      0t0  TCP bogon:ssh->bogon:15264 (ESTABLISHED)

    #查看init進程打開的文件
    />  lsof -c init
    COMMAND PID USER   FD   TYPE     DEVICE   SIZE/OFF   NODE    NAME
    init               1 root  cwd      DIR        8,2     4096              2        /
    init               1 root  rtd       DIR        8,2     4096              2        /
    init               1 root  txt       REG       8,2   136068       148567     /sbin/init
    init               1 root  mem    REG        8,2    58536      137507     /lib/libnss_files-2.12.so
    init               1 root  mem    REG        8,2   122232     186675     /lib/libgcc_s-4.4.4-20100726.so.1
    init               1 root  mem    REG        8,2   141492     186436     /lib/ld-2.12.so
    init               1 root  mem    REG        8,2  1855584    186631     /lib/libc-2.12.so
    init               1 root  mem    REG        8,2   133136     186632     /lib/libpthread-2.12.so
    init               1 root  mem    REG        8,2    99020      180422     /lib/libnih.so.1.0.0
    init               1 root  mem    REG        8,2    37304      186773     /lib/libnih-dbus.so.1.0.0
    init               1 root  mem    REG        8,2    41728      186633     /lib/librt-2.12.so
    init               1 root  mem    REG        8,2   286380     186634     /lib/libdbus-1.so.3.4.0
    init               1 root    0u     CHR        1,3      0t0           3671      /dev/null
    init               1 root    1u     CHR        1,3      0t0           3671      /dev/null
    init               1 root    2u     CHR        1,3      0t0           3671      /dev/null
    init               1 root    3r      FIFO       0,8      0t0           7969      pipe
    init               1 root    4w     FIFO       0,8      0t0           7969      pipe
    init               1 root    5r      DIR        0,10        0             1         inotify
    init               1 root    6r      DIR        0,10        0             1         inotify
    init               1 root    7u     unix   0xf61e3840  0t0       7970      socket
    init               1 root    9u     unix   0xf3bab280  0t0      11211     socket
    在上面輸出的FD列中,顯示的是文件的File Descriptor number,或者如下的內容:
    cwd:  current working directory;
    mem:  memory-mapped file;
    mmap: memory-mapped device;
    pd:   parent directory;
    rtd:  root directory;
    txt:  program text (code and data);
    文件的File Descriptor number顯示模式有:
    r for read access;
    w for write access;
    u for read and write access;

    在上面輸出的TYPE列中,顯示的是文件類型,如:
    DIR:  目錄
    LINK: 鏈接文件
    REG:  普通文件


    #查看pid爲1的進程(init)打開的文件,其輸出結果等同於上面的命令,他們都是init。
    /> lsof -p 1
    #查看owner爲root的進程打開的文件。
    /> lsof -u root
    #查看owner不爲root的進程打開的文件。
    /> lsof -u ^root
    #查看打開協議爲tcp,ip爲192.168.220.134,端口爲22的進程。
    /> lsof -i [email protected]:22
    COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    sshd        2829 root     3r    IPv4  19635      0t0      TCP    bogon:ssh->bogon:15264 (ESTABLISHED)   
    #查看打開/root文件夾,但不考慮目錄搜尋
    /> lsof +d /root
    #查看打開/root文件夾以及其子目錄搜尋
    /> lsof +D /root
    #查看打開FD(0-3)文件的所有進程
    /> lsof -d 0-3
    #-a選項會將+d選項和-c選項的選擇結果進行and操作,並輸出合併後的結果。
    /> lsof +d .
    COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
    bash       9707  root  cwd    DIR    8,1     4096         39887 .
    lsof         9791  root  cwd    DIR    8,1     4096         39887 .
    lsof         9792  root  cwd    DIR    8,1     4096         39887 .
    /> lsof -a -c bash +d .
    COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
    bash        9707 root  cwd    DIR    8,1     4096         39887 .
    最後需要額外說明的是,如果在文件名的末尾存在(delete),則說明該文件已經被刪除,只是還存留在cache中。


    4.  進程查找/殺掉命令(pgrep/pkill)
    查找和殺死指定的進程, 他們的選項和參數完全相同, 這裏只是介紹pgrep。下面是常用的命令行選項:

選項說明
-d定義多個進程之間的分隔符, 如果不定義則使用換行符。
-n表示如果該程序有多個進程正在運行,則僅查找最新的,即最後啓動的。
-o表示如果該程序有多個進程正在運行,則僅查找最老的,即最先啓動的。
-G其後跟着一組group id,該命令在搜索時,僅考慮group列表中的進程。
-u其後跟着一組有效用戶ID(effetive user id),該命令在搜索時,僅考慮該effective user列表中的進程。
-U其後跟着一組實際用戶ID(real user id),該命令在搜索時,僅考慮該real user列表中的進程。
-x表示進程的名字必須完全匹配, 以上的選項均可以部分匹配。
-l將不僅打印pid,也打印進程名。
-f一般與-l合用, 將打印進程的參數。

    #手工創建兩個後臺進程
    /> sleep 1000&
    3456
    /> sleep 1000&
    3457

    #查找進程名爲sleep的進程,同時輸出所有找到的pid
    /> pgrep sleep
    3456
    3457
    #查找進程名爲sleep的進程pid,如果存在多個,他們之間使用:分隔,而不是換行符分隔。
    /> pgrep -d: sleep
    3456:3457
    #查找進程名爲sleep的進程pid,如果存在多個,這裏只是輸出最後啓動的那一個。
    /> pgrep -n sleep
    3457
    #查找進程名爲sleep的進程pid,如果存在多個,這裏只是輸出最先啓動的那一個。
    /> pgrep -o  sleep
    3456
    #查找進程名爲sleep,同時這個正在運行的進程的組爲root和stephen。
    /> pgrep -G root,stephen sleep
    3456
    3457
    #查找有效用戶ID爲root和oracle,進程名爲sleep的進程。
    /> pgrep -u root,oracle sleep
    3456
    3457
    #查找實際用戶ID爲root和oracle,進程名爲sleep的進程。
    /> pgrep -U root,oracle sleep
    3456
    3457
    #查找進程名爲sleep的進程,注意這裏找到的進程名必須和參數中的完全匹配。
    /> pgrep -x sleep
    3456
    3457
    #-x不支持部分匹配,sleep進程將不會被查出,因此下面的命令沒有結果。
    /> pgrep -x sle
    #查找進程名爲sleep的進程,同時輸出所有找到的pid和進程名。    
    /> pgrep -l sleep
    3456 sleep
    3457 sleep
    #查找進程名爲sleep的進程,同時輸出所有找到的pid、進程名和啓動時的參數。
    /> pgrep -lf sleep
    3456 sleep 1000
    3457 sleep 1000
    #查找進程名爲sleep的進程,同時以逗號爲分隔符輸出他們的pid,在將結果傳給ps命令,-f表示顯示完整格式,-p顯示pid列表,ps將只是輸出該列表內的進程數據。
    /> pgrep -f sleep -d, | xargs ps -fp
    UID        PID  PPID  C STIME TTY          TIME CMD
    root      3456  2138  0 06:11 pts/5    00:00:00 sleep 1000
    root      3457  2138  0 06:11 pts/5    00:00:00 sleep 1000


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章