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 tcp@192.168.220.134: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?
總結
以上是生活随笔為你收集整理的Linux Shell常用技巧(九)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux Shell常用技巧(八)
- 下一篇: Linux Shell常用技巧(十)