程序與資源管理
本文資料主要針對 Fedora Core 4 的系統進行說明, Fedora Core 1 主要是由 Red Hat Linux 9 改版而來, 這個 Red Hat Linux 9 並不是當前大家聽到的 RHEL 喔!那是在 RHEL 出現之前的產品,基本上是在 2003 年以前的作品了!Fedora Core 4 則是在 2005 年 6 月份釋出,使用的核心是 2.6.11 版,當時是很紅的一個作品!只是生命週期太短,所以用這個 Fedora 系列來介紹 Server, 當時的決定確實有點莫名其妙了...
建議您前往本站查詢最新版本的 Linux distribution 文章來閱讀,比較不會浪費時間。那為何還需要編輯 Fedora Core 4 的資料呢? 鳥哥只想要做個自己曾經撰寫過的文件內容保存而已囉! ^_^!最新文章請前往鳥站首頁查閱囉!
在 Linux 當中, Linux 是如何分辨一個程序的呢?嗯!當我們的系統裡面有太多的死亡的程序的時候, 應該怎樣將該程序查出來之後並殺掉他呢?如果主機僅允許一次登入一個終端機畫面, 如何從事多個工作的進行呢?還有,如何設定一個程序,讓他的執行順序可以比較快速呢?! 這個都是程序控制的重點項目呦!呵呵!另外一個又更常發生啦!如果我的 X-Window 死掉了!但是我的 Linux 基本上卻還是活著的時候,那麼是否需要重新 reboot 呢?還是有其他的方式可以重新啟動 X-Window ? 仔細瞧一瞧整個 process 的概念喔!
例題:請在目前的 bash 環境下,再觸發一次 bash ,並以『 ps -l 』這個指令觀察程序相關的輸出資訊。 答:
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 0 S 500 21337 21336 0 75 0 - 1348 wait pts/1 00:00:00 bash 0 S 500 22573 21337 2 75 0 - 1348 wait pts/1 00:00:00 bash 0 R 500 22591 22573 0 76 0 - 1302 - pts/1 00:00:00 ps有看到那個 PID 與 PPID 嗎?第一個 bash 的 PID 與第二個 bash 的 PPID 都是 21337 啊, 因為第二個 bash 是來自於第一個所產生的嘛! |
[root@linux ~]# cp file1 file2 &
在這一串指令中,重點在那個 & 的功能,他表示將 file1 這個檔案複製為 file2 ,且放置於背景中執行,
也就是說執行這一個命令之後,在這一個終端介面仍然可以做其他的工作!而當這一個指令 (
cp file1 file2 )執行完畢之後,系統將會在您的終端介面顯示完成的消息!很便利喔![root@linux ~]# tar -zpcf /tmp/etc.tar.gz /etc & [1] 24874 <== [job number] PID [root@linux ~]# <== 可以繼續作業,不受影響!這就是前景!仔細的瞧一瞧,我在輸入一個指令後,在該指令的最後面加上一個『 & 』代表將該指令丟到背景中, 此時 bash 會給予這個指令一個『工作號碼(job number)』,就是那個 [1] 啦! 至於後面那個 24874 則是該指令所觸發的『 PID 』了! 而且,有趣的是,我們可以繼續操作 bash 呢!很不賴吧! 不過,那麼丟到背景中的工作什麼時候完成?完成的時候會顯示什麼? 如果你輸入幾個指令後,突然出現這個資料:
[1]+ Done tar -zpcf /tmp/etc.tar.gz /etc就代表 [1] 這個工作已經完成 (Done) ,該工作的指令則是接在後面那一串指令列。 這樣瞭解了吧?!另外,這個 & 代表:『將工作丟到背景中去執行』喔! 注意到那個『執行』的字眼!此外,這樣的情況最大的好處是: 不怕被 [ctrl]-c 中斷的啦!
[root@linux ~]# tar -zpcvf /tmp/etc.tar.gz /etc &
情況會怎樣?呵呵,在背景當中執行的指令,如果有 stdout 及 stderr 時,
他的資料依舊是輸出到螢幕上面的,所以,我們會無法看到提示字元,當然也就無法完好的掌握前景工作。
所以囉,最佳的狀況就是利用資料流重導向,將輸出資料傳送至某個檔案中。舉例來說,我可以這樣做:
[root@linux ~]# tar -zpcvf /tmp/etc.tar.gz /etc > /tmp/log.txt 2>&1 &
[1] 24984
[root@linux ~]#
呵呵!如此一來,資料都給他傳送到 /tmp/log.txt 當中,當然就不會影響到我們前景的作業了。
這樣說,您應該可以更清楚資料流重導向的重要性了吧?!^_^[root@linux ~]# vi ~/.bashrc # 在 vi 的一般模式下,按下 [ctrl]-z 這兩個按鍵 [1]+ Stopped /usr/bin/vim ~/.bashrc [root@linux ~]# <==順利取得了前景的操控權!在 vi 的一般模式下,按下 [ctrl] 及 z 這兩個按鍵,螢幕上會出現 [1] ,表示這是第一個工作, 而那個 + 代表目前在背景下預設被取用的那個工作 (與 fg 這個指令有關 )! 而那個 Stopped 則代表目前這個工作的狀態。在預設的情況下,使用 [ctrl]-z 丟到背景當中的工作都是『暫停』的狀態喔!
[root@linux ~]# jobs [-lrs] 參數: -l :除了列出 job number 之外,同時列出 PID -r :僅列出正在背景 run 的工作; -s :僅列出正在背景當中暫停 (stop) 的工作。 範例: 範例一:觀察目前的 bash 當中,所有的工作,與對應的 PID [root@linux ~]# jobs -l [1]+ 24988 Stopped /usr/bin/vim ~/.bashrc [2]- 25006 Stopped /usr/bin/vim ~/.bash_history如果想要知道目前有多少的工作在背景當中,就用 jobs 這個指令吧!一般來說,直接下達 jobs 即可! 不過,如果您還想要知道該 job number 的 PID 號碼,可以加上 -l 這個參數啦! 在輸出的資訊當中,例如上表,仔細看到那個 + - 號喔!那個 + 代表預設的取用工作。 所以說:『目前我有兩個工作在背景當中,兩個工作都是暫停的, 而如果我僅輸入 fg 時,那麼那個 [1] 會被拿到前景當中來處理』!
[root@linux ~]# fg %jobnumber 參數: %jobnumber :工作的號碼。注意,那個 % 是可有可無的! 範例: 範例一:先以 jobs 觀察工作,再將工作取出: [root@linux ~]# jobs [1]+ Stopped /usr/bin/vim ~/.bashrc [2]- Stopped /usr/bin/vim ~/.bash_history [root@linux ~]# fg <==預設取出那個 + 的工作,亦即 [1] [root@linux ~]# fg %2 <==直接規定取出的那個工作號碼!經過 fg 指令就能夠將背景工作拿到前景來處理囉!
範例一:一執行 find / -perm +7000 後,立刻丟到背景去暫停! [root@linux ~]# find / -perm +7000 # 此時,請立刻按下 [ctrl]-z 暫停! [1]+ Stopped find / -perm +7000 [root@linux ~]# 範例二:讓該工作在背景下進行,並且觀察他!! [root@linux ~]# jobs ; bg %1 ; jobs [1]+ Stopped find / -perm +7000 [1]+ find / -perm +7000 & [1]+ Running find / -perm +7000 &看到哪裡有差異嗎?呼呼!沒錯!就是那個狀態列~以經由 Stopping 變成了 Running 囉! 看到差異點,嘿嘿!指令列最後方多了一個 & 的符號囉! 代表該工作被啟動在背景當中了啦! ^_^
[root@linux ~]# kill -signal %jobnumber [root@linux ~]# kill -l 參數: -l :這個是 L 的小寫,列出目前 kill 能夠使用的訊號 (signal) 有哪些? signal :代表給予後面接的那個工作什麼樣的指示囉!用 man 7 signal 可知: -1 :重新讀取一次參數的設定檔 (類似 reload); -2 :代表與由鍵盤輸入 [ctrl]-c 同樣的動作; -9 :立刻強制刪除一個工作; -15:以正常的程序方式終止一項工作。與 -9 是不一樣的。 範例: 範例一:找出目前的 bash 環境下的背景工作,並將該工作刪除。 [root@linux ~]# jobs [1]+ Stopped vim bashrc [root@linux ~]# kill -9 %1 [1]+ 已砍掉 vim bashrc 範例:找出目前的 bash 環境下的背景工作,並將該工作終止掉。 [root@linux ~]# jobs [1]+ Stopped vim bashrc [root@linux ~]# kill -SIGTERM %1 [1]+ 終止 vim bashrc # -SIGTERM 與 -15 是一樣的!您可以使用 kill -l 來查閱!特別留意一下, -9 這個 signal 通常是用在『強制刪除一個不正常的工作』時所使用的, -15 則是以正常步驟結束一項工作(15也是預設值),兩者之間並不相同呦!舉上面的例子來說, 我用 vi 的時候,不是會產生一個 .filename.swp 的檔案嗎? 那麼,當使用 -15 這個 signal 時, vi 會嘗試以正常的步驟來結束掉該 vi 的工作, 所以 .filename.swp 會主動的被移除,但若是使用 -9 這個 signal 時, 由於該 vi 工作會被強制移除掉,因此, .filename.swp 就會繼續存在檔案系統當中。 這樣您應該可以稍微分辨一下了吧?
[root@linux ~]# ps aux [root@linux ~]# ps -lA [root@linux ~]# ps axjf 參數: -A :所有的 process 均顯示出來,與 -e 具有同樣的效用; -a :不與 terminal 有關的所有 process ; -u :有效使用者 (effective user) 相關的 process ; x :通常與 a 這個參數一起使用,可列出較完整資訊。 輸出格式規劃: l :較長、較詳細的將該 PID 的的資訊列出; j :工作的格式 (jobs format) -f :做一個更為完整的輸出。 特別說明: 由於 ps 能夠支援的 OS 類型相當的多,所以他的參數多的離譜! 而且有沒有加上 - 差很多!詳細的用法應該要參考 man ps 喔! 範例: 範例一:將目前屬於您自己這次登入的 PID 與相關資訊列示出來 [root@linux ~]# ps -l F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 0 S 0 5881 5654 0 76 0 - 1303 wait pts/0 00:00:00 su 4 S 0 5882 5881 0 75 0 - 1349 wait pts/0 00:00:00 bash 4 R 0 6037 5882 0 76 0 - 1111 - pts/0 00:00:00 ps # 上面這個資訊其實很多喔!各相關資訊的意義為: # F 代表這個程序的旗標 (flag), 4 代表使用者為 super user; # S 代表這個程序的狀態 (STAT),關於各 STAT 的意義將在內文介紹; # PID 沒問題吧!?就是這個程序的 ID 啊!底下的 PPID 則上父程序的 ID; # C CPU 使用的資源百分比 # PRI 這個是 Priority (優先執行序) 的縮寫,詳細後面介紹; # NI 這個是 Nice 值,在下一小節我們會持續介紹。 # ADDR 這個是 kernel function,指出該程序在記憶體的那個部分。如果是個 running # 的程序,一般就是『 - 』的啦! # SZ 使用掉的記憶體大小; # WCHAN 目前這個程序是否正在運作當中,若為 - 表示正在運作; # TTY 登入者的終端機位置囉; # TIME 使用掉的 CPU 時間。 # CMD 所下達的指令為何!? # 仔細看到每一個程序的 PID 與 PPID 的相關性為何喔!上頭列出的三個程序中, # 彼此間可是有相關性的吶! 範例二:列出目前所有的正在記憶體當中的程序: [root@linux ~]# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.1 1740 540 ? S Jul25 0:01 init [3] root 2 0.0 0.0 0 0 ? SN Jul25 0:00 [ksoftirqd/0] root 3 0.0 0.0 0 0 ? S< Jul25 0:00 [events/0] .....中間省略..... root 5881 0.0 0.3 5212 1204 pts/0 S 10:22 0:00 su root 5882 0.0 0.3 5396 1524 pts/0 S 10:22 0:00 bash root 6142 0.0 0.2 4488 916 pts/0 R+ 11:45 0:00 ps aux 範例三:以範例一的顯示內容,顯示出所有的程序: [root@linux ~]# ps -lA F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 1 0 0 76 0 - 435 - ? 00:00:01 init 1 S 0 2 1 0 94 19 - 0 ksofti ? 00:00:00 ksoftirqd/0 1 S 0 3 1 0 70 -5 - 0 worker ? 00:00:00 events/0 .....以下省略..... 範例四:列出類似程序樹的程序顯示: [root@linux ~]# ps -axjf PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 0 1 0 0 ? -1 S 0 0:01 init [3] 1 2 0 0 ? -1 SN 0 0:00 [ksoftirqd/0] .....中間省略..... 1 5281 5281 5281 ? -1 Ss 0 0:00 /usr/sbin/sshd 5281 5651 5651 5651 ? -1 Ss 0 0:00 \_ sshd: dmtsai [priv] 5651 5653 5651 5651 ? -1 S 500 0:00 \_ sshd: dmtsai@pts/0 5653 5654 5654 5654 pts/0 6151 Ss 500 0:00 \_ -bash 5654 5881 5881 5654 pts/0 6151 S 0 0:00 \_ su 5881 5882 5882 5654 pts/0 6151 S 0 0:00 \_ bash 5882 6151 6151 5654 pts/0 6151 R+ 0 0:00 \_ ps -axjf # 看出來了吧?其實鳥哥在進行一些測試時,都是以網路連線進主機來測試的, # 所以囉,你會發現,嘿嘿!其實程序之間是有相關性的啦!不過, # 其實還可以使用 pstree 來達成這個程序樹喔!底下在仔細談一談。 範例五:找出與 cron 與 syslog 這兩個服務有關的 PID 號碼? [root@linux ~]# ps aux | egrep '(cron|syslog)' root 1539 0.0 0.1 1616 616 ? Ss Jul25 0:03 syslogd -m 0 root 1676 0.0 0.2 4544 1128 ? Ss Jul25 0:00 crond root 6157 0.0 0.1 3764 664 pts/0 R+ 12:10 0:00 egrep (cron|syslog) # 所以號碼是 1539 及 1676 這兩個囉!就是這樣找的啦!說真的,如果你曾經使用 man ps 的話,呵呵!可能會被裡面的說明搞的一臉茫然~ 因為......支援的類型實在太多,所以, ps -aux 與 ps aux 顯示的結果『可能』是不一樣的, 那個 -u 後面接的是『有效的使用者 ID』,所以, -ux 可能是『有一個 user 名稱為 x 』 而如果沒有 x 這個使用者,那麼螢幕上面會顯示一個警告訊息,並以 ps aux 來輸出。 哇!真是麻煩~所以,您可以直接記得使用 ps aux 就好了!
root 5881 0.0 0.3 5212 1204 pts/0 S 10:22 0:00 su該程序屬於 root 所有,他的 PID 號碼是 5881,該程序對於 CPU 的使用率很低啊! 至於佔用的實體記憶體大概有 0.3% 這麼多。至於該程序使用掉的虛擬記憶體量為 5212 K, 實體記憶體為 1204 K,該程序屬於 pts/0 這個終端機,看來這個程序應該是來自網路的連線登入。 該程序目前是 Sleep 的狀態,但其實是可以被執行的。這個程序由今天的 10:22 開始運作, 不過,僅耗去 CPU 運作時間的 0:00 分鐘。該程序的執行就是 su 這個指令啦!
apache 8683 0.0 0.9 83384 9992 ? Z 14:33 0:00 /usr/sbin/httpd <defunct>當系統不穩定的時候就容易造成所謂的疆屍程序,可能原因是因為程式寫的不好啦, 或者是使用者的操作習慣不良等等所造成。如果您發現系統中很多疆屍程序時, 呵呵!記得啊!要找出該程序的父程序,然後好好的做個追蹤,好好的進行主機的環境最佳化啊! 看看有什麼地方需要改善的,不要只是直接將他 kill 掉而已呢! 不然的話,萬一他一直產生,那可就麻煩了! @_@
[root@linux ~]# top [-d] | top [-bnp] 參數: -d :後面可以接秒數,就是整個程序畫面更新的秒數。預設是 5 秒; -b :以批次的方式執行 top ,還有更多的參數可以使用喔! 通常會搭配資料流重導向來將批次的結果輸出成為檔案。 -n :與 -b 搭配,意義是,需要進行幾次 top 的輸出結果。 -p :指定某些個 PID 來進行觀察監測而已。 在 top 執行過程當中可以使用的按鍵指令: ? :顯示在 top 當中可以輸入的按鍵指令; P :以 CPU 的使用資源排序顯示; M :以 Memory 的使用資源排序顯示; N :以 PID 來排序喔! T :由該 Process 使用的 CPU 時間累積 (TIME+) 排序。 k :給予某個 PID 一個訊號 (signal) r :給予某個 PID 重新制訂一個 nice 值。 範例: 範例一:每兩秒鐘更新一次 top ,觀察整體資訊: [root@linux ~]# top -d 2 top - 18:30:36 up 30 days, 7 min, 1 user, load average: 0.42, 0.48, 0.45 Tasks: 163 total, 1 running, 161 sleeping, 1 stopped, 0 zombie Cpu(s): 4.7% us, 4.0% sy, 6.3% ni, 82.5% id, 0.4% wa, 0.1% hi, 2.0% si Mem: 1033592k total, 955252k used, 78340k free, 208648k buffers Swap: 1052216k total, 728k used, 1051488k free, 360248k cached <==如果加入 k 或 r 時,就會有相關的字樣出現在這裡喔! PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 3981 apache 34 19 84012 11m 7352 S 17.3 1.2 0:00.09 httpd 1454 mysql 16 0 289m 40m 2228 S 3.8 4.0 115:01.32 mysqld 3985 dmtsai 15 0 2148 904 668 R 3.8 0.1 0:00.03 top 1 root 16 0 3552 552 472 S 0.0 0.1 0:08.90 init 2 root RT 0 0 0 0 S 0.0 0.0 0:52.76 migration/0 3 root 34 19 0 0 0 S 0.0 0.0 0:03.01 ksoftirqd/0 範例二:將 top 的資訊進行 2 次,然後將結果輸出到 /tmp/top.txt [root@linux ~]# top -b -n 2 > /tmp/top.txt # 這樣一來,嘿嘿!就可以將 top 的資訊存到 /tmp/top.txt 檔案中了。 範例三:假設 10604 是一個已經存在的 PID ,僅觀察該程序? [root@linux ~]# top -d 2 -p10604 top - 13:53:00 up 51 days, 2:27, 1 user, load average: 0.00, 0.00, 0.00 Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie Cpu(s): 0.0% us, 0.0% sy, 0.0% ni, 100.0% id, 0.0% wa, 0.0% hi, 0.0% si Mem: 385676k total, 371760k used, 13916k free, 131164k buffers Swap: 1020116k total, 880k used, 1019236k free, 95772k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 10604 root 16 0 5396 1544 1244 S 0.0 0.4 0:00.07 bash 範例四:承上題,上面的 NI 值是 0 ,想要改成 10 的話? # 在範例三的 top 畫面當中直接按下 r 之後,會出現如下的圖樣! top - 13:53:00 up 51 days, 2:27, 1 user, load average: 0.00, 0.00, 0.00 Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie Cpu(s): 0.0% us, 0.0% sy, 0.0% ni, 100.0% id, 0.0% wa, 0.0% hi, 0.0% si Mem: 385676k total, 371760k used, 13916k free, 131164k buffers Swap: 1020116k total, 880k used, 1019236k free, 95772k cached PID to renice: 10604 PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 10604 root 16 0 5396 1544 1244 S 0.0 0.4 0:00.07 bash # 之後,可以輸入 nice 值了! top - 13:53:00 up 51 days, 2:27, 1 user, load average: 0.00, 0.00, 0.00 Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie Cpu(s): 0.0% us, 0.0% sy, 0.0% ni, 100.0% id, 0.0% wa, 0.0% hi, 0.0% si Mem: 385676k total, 371760k used, 13916k free, 131164k buffers Swap: 1020116k total, 880k used, 1019236k free, 95772k cached Renice PID 10604 to value: 10 PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 10604 root 30 10 5396 1544 1244 S 0.0 0.4 0:00.07 bashtop 也是個挺不錯的程序觀察工具!但不同於 ps 是靜態的結果輸出, top 這個程式可以持續的監測 (monitor) 整個系統的程序工作狀態,例如上面的範例一所示啊! 在預設的情況下,每次更新程序資源的時間為 5 秒,不過,可以使用 -d 來進行修改。
[root@linux ~]# pstree [-Aup] 參數: -A :各程序樹之間的連接以 ASCII 字元來連接; -p :並同時列出每個 process 的 PID; -u :並同時列出每個 process 的所屬帳號名稱。 範例: 範例一:列出目前系統上面所有的程序樹的相關性: [root@linux ~]# pstree -A init-+-atd |-crond |-dhclient |-dovecot-+-dovecot-auth | `-3*[pop3-login] |-events/0 |-2*[gconfd-2] |-master-+-pickup | `-qmgr |-6*[mingetty] |-sshd---sshd---sshd---bash---su---bash---pstree |-udevd `-xinetd # 注意一下,為了節省版面,所以鳥哥已經刪去很多程序了! # 同時注意到 sshd--- 那一行,嘿嘿!有相關的程序都被列出在一起了! 範例二:承上題,同時秀出 PID 與 users [root@linux ~]# pstree -Aup init(1)-+-atd(16143) |-crond(1676) |-dhclient(21339) |-dovecot(1606)-+-dovecot-auth(1616) | |-pop3-login(747,dovecot) | |-pop3-login(10487,dovecot) | `-pop3-login(10492,dovecot) |-events/0(3) |-gconfd-2(2352) |-gconfd-2(32158) |-master(1666)-+-pickup(10817,postfix) | `-qmgr(1675,postfix) |-mingetty(1792) |-mingetty(21366) |-sshd(5281)---sshd(10576)---sshd(10578,vbird)---bash(10579) |-syslogd(1539) |-udevd(801) `-xinetd(1589) # 呵呵!在括號 () 內的即是 PID 以及該程序的 owner 喔!不過,由於我是使用 # root 的身份執行此一指令,所以囉,嘿嘿!屬於root的可能就不會顯示出來啦!如果要找程序之間的相關性,呵呵!這個 pstree 真是好用到不行! 直接輸入 pstree 可以查到程序相關性,不過,有的時候由於語系的問題會出現亂碼, 因此,建議直接使用 -A 用 ASCII 字元作為連結介面 (就是那個 +, -, |, ` 等等啦!) 會比較看的清楚點。另外,如果還想要知道 PID 與所屬使用者,加上 -u 及 -p 兩個參數即可。 我們前面不是一直提到,如果子程序掛點或者是老是砍不掉子程序時, 該如何找到父程序嗎?呵呵!用這個 pstree 就對了! ^_^
代號 | 名稱 | 內容 |
1 | SIGHUP | 代表『讓該 PID 重新讀取自己的設定檔』 ,類似重新啟動 |
2 | SIGINT | 代表用鍵盤輸入的 [ctrl]-c 來中斷一個程序的進行。 |
9 | SIGKILL | 代表強制中斷一個程序的進行,如果該程序進行到一半, 那麼尚未完成的部分可能會有『半產品』產生,類似 vim會有 .filename.swp 保留下來。 |
15 | SIGTERM | 以正常的結束程序來終止該程序。由於是正常的終止, 所以後續的動作會將他完成。不過,如果該程序已經發生問題,就是無法使用正常的方法終止時, 輸入這個 signal 也是沒有用的。 |
例題:以 ps 找出 syslog 這個服務的 PID 後,再使用 kill 重新讀取 syslog 的設定檔資料: 答:
|
[root@linux ~]# killall [-iIe] [command name] 參數: -i :interactive 的意思,互動式的,若需要刪除時,會出現提示字元給使用者; -e :exact 的意思,表示『後面接的 command name 要一致』,但整個完整的指令 不能超過 15 個字元。 -I :指令名稱(可能含參數)忽略大小寫。 範例: 範例一:給予 syslogd 這個指令啟動的 PID 一個 SIGHUP 的訊號 [root@linux ~]# killall -1 syslogd # 如果用 ps aux 仔細看一下,syslogd 才是完整的指令名稱。但若包含整個參數, # 則 syslogd -m 0 才是完整的呢! 範例二:強制終止所有以 httpd 啟動的程序 [root@linux ~]# killall -9 httpd總之,要刪除某個程序,我們可以使用 PID 或者是啟動該程序的指令名稱, 而如果要刪除某個服務呢?呵呵!最簡單的方法就是利用 killall , 因為他可以將系統當中所有以某個指令名稱啟動的程序全部刪除。 舉例來說,上面的範例二當中,系統內所有以 httpd 啟動的程序,就會通通的被刪除啦! ^_^
[root@linux ~]# free [-b|-k|-m|-g] [-t] 參數: -b :直接輸入 free 時,顯示的單位是 Kbytes,我們可以使用 b(bytes), m(Mbytes) k(Kbytes), 及 g(Gbytes) 來顯示單位喔! -t :在輸出的最終結果,顯示實體記憶體與 swap 的總量。 範例: 範例一:顯示目前系統的記憶體容量 [root@linux ~]# free -m total used free shared buffers cached Mem: 376 366 10 0 129 94 -/+ buffers/cache: 141 235 Swap: 996 0 995仔細看看,我的系統當中有 384 MB 左右的實體記憶體,我的 swap 有 1GB 左右, 那我使用 free -m 以 MBytes 來顯示時,就會出現上面的資訊。Mem 那一行顯示的是實體記憶體的量, Swap 則是虛擬記憶體的量。 total 是總量, used 是已被使用的量, free 則是剩餘可用的量。 後面的 shared/buffers/cached 則是在已被使用的量當中,用來作為緩衝及快取的量。
[root@linux ~]# uname [-asrmpi] 參數: -a :所有系統相關的資訊; -s :系統核心名稱 -r :核心的版本 -m :本系統的硬體名稱 -p :CPU 的類型 -i :硬體的平台 (ix86) 範例: 範例一:輸出系統的基本資訊 [root@linux ~]# uname -a Linux linux.site 2.6.12-1.1398_FC4 #1 Fri Jul 15 00:52:32 EDT 2005 i686 i686 i386 GNU/Linux這個咚咚我們前面使用過很多次了喔!uname 可以列出目前系統的核心版本、 主要硬體平台以及 CPU 類型等等的資訊。以上面範例一的狀態來說,我的 Linux 主機使用的核心名稱為 Linux,而主機名稱為 linux.site,核心的版本為 2.6.12-1.1398_FC4,該核心版本建立的日期為 2005/07/15, 適用的硬體平台為 i386 以上等級的硬體平台喔。
[root@linux ~]# uptime 18:06:30 up 52 days, 6:40, 1 user, load average: 0.00, 0.00, 0.00 # 上面表示,目前是 18:06 ,本系統已經開機 52 天又 6:40 ,有 1 個使用者在線上, # 平均負載很低,所以都是 0 啊!
[root@linux ~]# netstat -[atunlp] 參數: -a :將目前系統上所有的連線、監聽、Socket 資料都列出來 -t :列出 tcp 網路封包的資料 -u :列出 udp 網路封包的資料 -n :不已程序的服務名稱,以埠號 (port number) 來顯示; -l :列出目前正在網路監聽 (listen) 的服務; -p :列出該網路服務的程序 PID 範例: 範例一:列出目前系統已經建立的網路連線與 unix socket 狀態 [root@linux ~]# netstat Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 256 59-125-83-224.ad:ssh linux.test.s:52679 ESTABLISHED Active UNIX domain sockets (w/o servers) Proto RefCnt Flags Type State I-Node Path unix 16 [ ] DGRAM 4870 /dev/log unix 2 [ ] DGRAM 3561 @udevd unix 3 [ ] STREAM CONNECTED 509237 # 在上面的結果當中,顯示了兩個部分,分別是網路的連線以及 linux 上面的 socket # 連線狀態。在網路連線的部分主要內容為: # Proto :網路的封包協定,主要分為 TCP 與 UDP 封包,相關資料請參考伺服器篇; # Recv-Q:非由使用者程式連結到此 socket 的複製的總 bytes 數; # Send-Q:非由遠端主機傳送過來的 acknowledged 總 bytes 數; # Local Address :本地端的 IP # Foreign Address:遠端主機的 IP; # State :連線狀態,主要有建立(ESTABLISED)及監聽(LISTEN); # 至於 unix 傳統的 socket 連接狀態則是: # Proto :一般就是 unix 啦; # RefCnt:連接到此 socket 的程序數量; # Flags :連線的旗標; # Type :socket 存取的類型。主要有確認連線的 STREAM 與不需確認的 DGRAM 兩種; # State :CONNECTED 表示已經連線建立。 # Path :連接到此 socket 的相關程式的路徑!或者是相關資料輸出的路徑。 範例二:找出目前系統上已在監聽的網路連線及其 PID [root@linux ~]# netstat -tulnp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN 1598/vsftpd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1666/master tcp 0 0 :::22 :::* LISTEN 5281/sshd udp 0 0 0.0.0.0:68 0.0.0.0:* 21339/dhclient # 看到了嗎?最後面一個欄位就是該埠號被該 PID 或程式所啟動的! 範例三:將上述的本地端 0.0.0.0:21 那個網路服務關閉的話? [root@linux ~]# kill 1598 [root@linux ~]# killall vsftpd很多朋友常常有疑問,那就是,我的主機目前到底開了幾個門(ports), 呵呵!其實,不論主機提供什麼樣的服務,一定必須要有相對應的 program 在主機上面執行才行啊! 舉例來說,我們鳥園的 Linux 主機提供的就是 WWW 服務,那麼我的主機當然有一個程式在提供 WWW 的服務啊!呵呵!那就是 Apache 這個套件所提供的啦! ^_^。 所以,當我執行了這個程式之後,我的系統自然就可以提供 WWW 的服務了。那如何關閉啊? 就關掉該程式所觸發的那個程序就好了!例如上面的範例三所提供的例子啊! ^_^
範例一:輸出所有的核心開機時的資訊 [root@linux ~]# dmesg | more 範例二:搜尋開機的時候,硬碟的相關資訊為何? [root@linux ~]# dmesg | grep -i hd ide0: BM-DMA at 0xffa0-0xffa7, BIOS settings: hda:DMA, hdb:DMA ide1: BM-DMA at 0xffa8-0xffaf, BIOS settings: hdc:DMA, hdd:pio hda: ST320430A, ATA DISK drive hdb: Maxtor 5T030H3, ATA DISK drive hdc: CD-540E, ATAPI CD/DVD-ROM drive .....底下省略.....由範例二就知道我這部主機的硬碟是怎樣了吧?!沒錯啦! 還可以查閱能不能找到網路卡喔!網路卡的代號是 eth ,所以,直接輸入 dmesg | grep -i eth 試看看呢!
[root@linux ~]# sar [-ru] [秒數] [次數] 參數: -u :進行 CPU 資源的統計; -r :進行主記憶體目前狀態的分析 範例: 範例一:統計目前主機 CPU 狀態,每秒一次,共計三次! [root@linux ~]# sar -u 1 3 Linux 2.6.12-1.1398_FC4 (vbird.vbird.idv.tw) 09/16/05 14:16:17 CPU %user %nice %system %iowait %idle 14:16:18 all 0.00 0.00 0.00 0.00 100.00 14:16:19 all 0.00 0.00 0.00 0.00 100.00 14:16:20 all 0.00 0.00 0.00 0.00 100.00 Average: all 0.00 0.00 0.00 0.00 100.00 # 我這部主機單純用在家裡測試的,所以沒有什麼網路服務,看的出來,嘿嘿!很安靜! 範例二:統計目前主機記憶體的使用情況 [root@linux ~]# sar -r 1 3 Linux 2.6.12-1.1398_FC4 (vbird.vbird.idv.tw) 09/16/05 14:17:40 kbmemfree kbmemused %memused kbbuffers kbcached kbswpfree 14:17:41 26004 359672 93.26 127528 83996 1019236 14:17:42 26004 359672 93.26 127528 83996 1019236 14:17:43 26004 359672 93.26 127528 83996 1019236 Average: 26004 359672 93.26 127528 83996 1019236 # 其實這個與 free 的輸出結果也差不了太多啦!鳥哥倒是很喜歡使用 sar 來做背景主動偵測系統 CPU 的動作!參考看看先!
[root@linux ~]# ps -l F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 0 S 0 18851 18827 0 77 0 - 1302 wait pts/0 00:00:00 su 4 S 0 18852 18851 0 76 0 - 1349 wait pts/0 00:00:00 bash 4 R 0 19510 18852 0 76 0 - 1111 - pts/0 00:00:00 ps其中,那個 PRI 就是 Priority 的簡寫,而 NI 是 nice 的簡寫,這兩個東西是湊在一起才產生目前的 PRI 值的! PRI 越小時,代表該程序可以具有『越早被優先執行』的意思,只是 PRI 是由系統動態產生的, 並不會是一直固定的值喔。至於那個 NI (nice) 則是我們操作值額外給予的一個數值, 他可以影響 PRI 的值,基本上,他的相關性是這樣的:
[root@linux ~]# nice [-n] command 參數: -n :後面接一個數值,數值的範圍 -20 ~ 19。 範例: 範例一:用 root 給一個 nice 植為 -5 ,用於執行 vi ,並觀察該程序! [root@linux ~]# nice -n -5 vi & [1] 19542 [root@linux ~]# ps -l F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 0 S 0 18851 18827 0 77 0 - 1302 wait pts/0 00:00:00 su 4 S 0 18852 18851 0 76 0 - 1349 wait pts/0 00:00:00 bash 4 T 0 19542 18852 0 72 -5 - 1063 finish pts/0 00:00:00 vi 4 R 0 19543 18852 0 77 0 - 1110 - pts/0 00:00:00 ps就如同前面說的, nice 是用來調整程序的執行優先順序!這裡只是一個執行的範例罷了! 通常什麼時候要將 nice 值調大呢?舉例來說,系統的背景工作中, 某些比較不重要的程序之進行:例如備份工作!由於備份工作相當的耗系統資源, 這個時候就可以將備份的指令之 nice 值調大一些,可以使系統的支援分配的更為公平!
[root@linux ~]# renice [number] PID 參數: PID :某個程序的 ID 啊! 範例: 範例一:以上面 nice 範例中 ps -l 的結果,將 18852 那個 PID 修改 nice 為 10 [root@linux ~]# renice 10 18852 18852: old priority 0, new priority 10 [root@linux ~]# ps -l F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 0 S 0 18851 18827 0 77 0 - 1302 wait pts/0 00:00:00 su 4 S 0 18852 18851 0 85 10 - 1349 wait pts/0 00:00:00 bash 4 R 0 19593 18852 0 87 10 - 1111 - pts/0 00:00:00 ps如果要調整的是已經存在的某個 process 的話,那麼就得要使用 renice 了。使用的方法很簡單, renice 後面接上數值及 PID 即可。因為後面接的是 PID ,所以您務必要以 ps 或者其他程序觀察的指令去找出 PID 才行啊!
init-+-atd |-.....省略的啦.......... |-sshd---sshd---bash(dmtsai)---passwd(root) |-.....省略的啦.......... `-xinetd看到了吧?雖然我是以 dmtsai 的身份啟動 bash ,然後在 bash 當中執行 /usr/bin/passwd, 不過由於 passwd 擁有 SUID 的權限設定,所以,在 run-time 的過程當中,嘿嘿! 我這個 dmtsai 在該 process 內可是擁有 /usr/bin/passwd 的 owner (亦即是 root ) 的權限喔!這樣夠明白了吧?!
[root@linux ~]# ll /proc dr-xr-xr-x 5 root root 0 Sep 12 14:12 1 dr-xr-xr-x 5 root root 0 Sep 15 12:01 10 dr-xr-xr-x 5 dovecot dovecot 0 Sep 14 12:07 10487 .....中間省略..... -r--r--r-- 1 root root 0 Sep 16 16:02 uptime -r--r--r-- 1 root root 0 Sep 16 16:02 version -r--r--r-- 1 root root 0 Sep 16 16:02 vmstat基本上,目前主機上面的各個程序的 PID 都是以目錄的型態存在於 /proc 當中。 舉例來說,我們開機所執行的第一支程式 init 他的 PID 是 1 , 這個 PID 的所有相關資訊都寫入在 /proc/1/* 當中!若我們直接觀察 PID 為 1 的資料好了, 他有點像這樣:
[root@linux ~]# ll /proc/1 dr-xr-xr-x 2 root root 0 Sep 16 16:04 attr -r-------- 1 root root 0 Sep 16 16:04 auxv -r--r--r-- 1 root root 0 Sep 16 10:23 cmdline lrwxrwxrwx 1 root root 0 Sep 16 10:23 cwd -> / -r-------- 1 root root 0 Sep 16 16:04 environ lrwxrwxrwx 1 root root 0 Sep 16 10:23 exe -> /sbin/init .....以下省略.....裡面的資料還挺多的,不過,比較有趣的其實是兩個檔案,分別是:
[root@linux ~]# cat /proc/1/cmdline
init [3]
就是這個指令與參數啟動 init 的啦!這還是跟某個特定的 PID 有關的內容呢,如果是針對整個
Linux 系統相關的參數呢?那就是在 /proc 目錄底下的檔案啦!相關的檔案與對應的內容是這樣的:檔名 | 檔案內容 |
/proc/cmdline | 載入 kernel 時所下達的相關參數!查閱此檔案,可瞭解系統是如何啟動的! |
/proc/cpuinfo | 本機的 CPU 的相關資訊,包含時脈、類型與運算功能等 |
/proc/devices | 這個檔案記錄了系統各個主要裝置的主要裝置代號,與 mknod 有關呢! |
/proc/filesystems | 目前系統已經載入的檔案系統囉! |
/proc/interrupts | 目前系統上面的 IRQ 分配狀態。 |
/proc/ioports | 目前系統上面各個裝置所配置的 I/O 位址。 |
/proc/kcore | 這個就是記憶體的大小啦!好大對吧!但是不要讀他啦! |
/proc/loadavg | 還記得 top 以及 uptime 吧?沒錯!上頭的三個平均數值就是記錄在此! |
/proc/meminfo | 使用 free 列出的記憶體資訊,嘿嘿!在這裡也能夠查閱到! |
/proc/modules | 目前我們的 Linux 已經載入的模組列表,也可以想成是驅動程式啦! |
/proc/mounts | 系統已經掛載的資料,就是用 mount 這個指令呼叫出來的資料啦! |
/proc/swaps | 到底系統掛載入的記憶體在哪裡?呵呵!使用掉的 partition 就記錄在此啦! |
/proc/partitions | 使用 fdisk -l 會出現目前所有的 partition 吧?在這個檔案當中也有紀錄喔! |
/proc/pci | 在 PCI 匯流排上面,每個裝置的詳細情況!可用 lspci 來查閱! |
/proc/uptime | 就是用 uptime 的時候,會出現的資訊啦! |
/proc/version | 核心的版本,就是用 uname -a 顯示的內容啦! |
/proc/bus/* | 一些匯流排的裝置,還有 USB 的裝置也記錄在此喔! |
[root@linux ~]# fuser [-ki] [-signal] file/dir 參數: -k :找出使用該檔案/目錄的 PID ,並試圖以 SIGKILL 這個訊號給予該 PID; -i :必須與 -k 配合,在刪除 PID 之前會先詢問使用者意願! -signal:例如 -1 -15 等等,若不加的話,預設是 SIGKILL (-9) 囉! 範例: 範例一:找出目前所在目錄的使用 PID 為何? [root@linux ~]# fuser . .: 18852c [root@linux ~]# ps aux | grep 18852 root 18852 0.0 0.4 5396 1588 pts/0 SN 10:12 0:00 bash # 用這個方式就可以得到使用該目錄的 PID 了。此外,為何使用 fuser # 的輸出當中,在 PID 後面會有 c 呢?他代表的意義為: # c :在當前的目錄下; # e :可以被執行的; # f :是一個被開啟的檔案 # r :代表 root directory 範例二:找到 /var 底下屬於 FIFO 類型的檔案,並且找出存取該檔案的程序 [root@linux ~]# find /var -type p /var/spool/postfix/public/qmgr /var/spool/postfix/public/pickup [root@linux ~]# fuser /var/spool/postfix/public/qmgr /var/spool/postfix/public/qmgr: 1666 1675 [root@linux ~]# ps aux | egrep '(1666|1675)' root 1666 0.0 0.3 5640 1516 ? Ss Jul25 0:01 /usr/libexec/postfix/master postfix 1675 0.0 0.4 5744 1604 ? S Jul25 0:00 qmgr -l -t fifo -u 範例三:同範例二,但試圖刪除該 PID? [root@linux ~]# fuser -ki /var/spool/postfix/public/qmgr /var/spool/postfix/public/qmgr: 1666 1675 Kill process 1666 ? (y/N) n Kill process 1675 ? (y/N) n如何?很有趣的一個指令吧!透過這個 fuser 我們可以找出使用該檔案、 目錄的程序,藉以觀察的啦!
[root@linux ~]# lsof [-Uu] [+d] 參數: -a :多項資料需要『同時成立』才顯示出結果時! -U :僅列出 Unix like 系統的 socket 檔案類型; -u :後面接 username,列出該使用者相關程序所開啟的檔案; +d :後面接目錄,亦即找出某個目錄底下已經被開啟的檔案! 範例: 範例一:列出目前系統上面所有已經被開啟的檔案與裝置: [root@linux ~]# lsof COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME init 1 root cwd DIR 3,1 4096 2 / init 1 root rtd DIR 3,1 4096 2 / init 1 root txt REG 3,1 34352 883193 /sbin/init .....底下省略..... # 注意到了嗎?是的,在預設的情況下, lsof 會將目前系統上面已經開啟的 # 檔案全部列出來~所以,畫面多的嚇人啊!您可以注意到,第一個檔案 init 執行的 # 地方就在根目錄,而根目錄,嘿嘿!所在的 inode 也有顯示出來喔! 範例二:僅列出關於 root 的所有程序開啟的 socket 檔案 [root@linux ~]# lsof -u root -a -U COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME kmodule 793 root 4u unix 0xd744b700 3549 socket udevd 801 root 5u unix 0xd744bb40 3561 socket syslogd 1539 root 0u unix 0xd75946e0 4870 /dev/log # 注意到那個 -a 吧!如果你分別輸入 lsof -u root 及 lsof -U ,會有啥資訊? # 使用 lsof -u root -U 及 lsof -u root -a -U ,呵呵!都不同啦! # -a 的用途就是在解決同時需要兩個項目都成立時啊! ^_^ 範例三:請列出目前系統上面所有的被啟動的周邊裝置 [root@linux ~]# lsof +d /dev COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME init 1 root 10u FIFO 0,13 1834 /dev/initctl kmodule 793 root 2u CHR 1,3 2135 /dev/null kmodule 793 root 3u CHR 5,1 2134 /dev/console udevd 801 root 2u CHR 1,3 2135 /dev/null syslogd 1539 root 0u unix 0xd75946e0 4870 /dev/log xinetd 1589 root 1r CHR 1,3 2135 /dev/null #看吧!因為裝置都在 /dev 裡面嘛!所以囉,使用搜尋目錄即可啊! 範例四:秀出屬於 root 的 bash 這支程式所開啟的檔案 [root@linux ~]# lsof -u root | grep bash bash 26199 root cwd DIR 3,2 4096 159875 /root bash 26199 root rtd DIR 3,1 4096 2 / bash 26199 root txt REG 3,1 686520 294425 /bin/bash bash 26199 root mem REG 3,1 83160 32932 /usr/lib/gconv/BIG5.so bash 26199 root mem REG 3,1 46552 915764 /lib/libnss_files-2.3.5.so .....底下省略.....這個指令可以找出您想要知道的某個程序是否有啟用哪些資訊? 例如上頭提到的範例四的執行結果呢! ^_^
[root@linux ~]# pidof [-sx] program_name 參數: -s :僅列出一個 PID 而不列出所有的 PID -x :同時列出該 program name 可能的 PPID 那個程序的 PID 範例: 範例一:列出目前系統上面 init 以及 syslogd 這兩個程式的 PID [root@linux ~]# pidof init syslogd 1 2546 # 理論上,應該會有兩個 PID 才對。上面的顯示也是出現了兩個 PID 喔。 # 分別是 init 及 syslogd 這兩支程式的 PID 啦。 範例二:找出 bash 即以 bash 為 PPID 的幾個主要的 PID [root@linux ~]# pidof -x bash 2961 2959 338 # 因為我的系統被我登入之後,我就會主動取得一個 bash 的程序,所以囉, # 很自然就會擁有一個 PID 啊。只要我再以底下的方式,就可以取得我所想要的 PID 內容。 [root@linux ~]# ps aux | egrep '(2961|2959|338)' dmtsai 338 0.0 0.1 6024 1536 pts/0 Ss 16:43 0:00 -bash kiki 2961 0.0 0.1 6025 1526 pts/0 Ss 17:43 0:00 -bash .....以下省略......很簡單的用法吧,透過這個 pidof 指令,並且配合 ps aux 與正規表示法, 就可以很輕易的找到您所想要的程序內容了呢。