Linux 基礎學習篇 - Fedora Core 4

第十七章、程序與資源管理 - for Fedora Core 4

程序與資源管理

最近更新時間: 2005/09/18

本文資料主要針對 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 的概念喔!

什麼是程序 (process)

由前面一連幾個章節的資料看來,我們一直強調在 Linux 底下所有的指令與您能夠進行的動作都與權限有關, 而系統如何判定你的權限呢?當然就是前面 帳號管理 章節當中提到的 UID/GID 的相關概念,以及檔案的屬性相關性囉!再進一步來解釋, 您現在大概知道,在 Linux 系統當中:『觸發任何一個事件時, 系統都會將他定義成為一個程序,並且給予這個程序一個 ID ,稱為 PID,同時依據啟發這個程序的使用者與相關屬性關係, 給予這個 PID 一組有效的權限設定。』 從此以後,這個 PID 能夠在系統上面進行的動作,就與這個 PID 的權限有關了!

看這個定義似乎沒有什麼很奇怪的地方,不過,您得要瞭解什麼叫做『觸發事件』才行啊! 我們在什麼情況下會觸發一個事件?而同一個事件可否被觸發多次?呵呵!來瞭解瞭解先!

程序與執行檔 (process & program)

我們如何產生一個 Process ID (PID) 呢?其實很簡單啦,就是『執行一個程式或指令』 就可以觸發一個事件了而取得一個 PID 囉!我們說過,系統應該是僅認識 binary file 的, 那麼當我們要讓系統工作的時候,當然就是需要啟動一個 binary file 囉, 那個 binary file 就是程式 (program) 啦!

那我們知道,每個程式都有三組人馬的權限,每組人馬都具有 r/w/x 的權限, 所以:『不同的使用者身份執行這個 program 時,系統給予的權限也都不相同!』 舉例來說,我們可以利用 touch 來建立一個空的檔案,當 root 執行這個 touch 指令時,他取得的是 UID/GID = 0/0 的權限,而當 dmtsai (UID/GID=501/501) 執行這個 touch 時,他的權限就跟 root 不同啦!

再舉個更常見的例子,我們要操作系統的時候,通常是利用連線程式或者直接在主機前面登入, 然後取得我們的 shell 對吧!那麼,我們的 shell 是 bash 對吧,這個 bash 在 /bin/bash 對吧, 那麼同時間的每個人登入都是執行 /bin/bash 對吧!不過,每個人取得的權限就是不同! 也就是說,我們可以這樣看:
程式與程序之間的差異
圖一、程式與程序之間的差異

也就是說,當我們登入並執行 bash 時,系統已經給我們一個 PID 了, 這個 PID 就是依據登入者的 UID/GID (/etc/passwd) 來的啦~ 以上面的圖來做說明的話,我們知道 /bin/bash 是一個程式 (program),當 dmtsai 登入後,他取得一個 PID 號碼為 2234 的程序,這個程序的 User/Group 都是 dmtsai, 而當這個程式進行其他作業時,例如上面提到的 touch 這個指令時, 那麼由這個程序衍生出來的其他程序在一般狀態下,也會沿用這個程序的相關權限的!


  • 子程序與父程序:
  • 在上面的說明裡面,我們有提到所謂的『衍生出來的程序』,那是個啥咚咚? 這樣說好了,當我們登入系統後,會取得一個 bash 的 shell ,然後,我們用這個 bash 提供的介面去執行另一個指令,例如 /usr/bin/passwd 或者是 touch 等等, 那些另外執行的指令也會被觸發成為 PID ,呵呵!那個 PID 就是『子程序』了, 而在我們的 bash 環境下,就稱為『父程序』了!

    另外,是否還記得我們在 bash shell 那一篇裡面有提到 『環境變數』在不同程序之間的呼叫呢?現在稍微曉得是什麼意思了嗎? 是啦!因為我們有執行不同的 bash 嘛!既然執行兩次,自然就會取得兩個 PID, 而因為要讓兩個 PID 之間具有一些相關性,我們的 bash 就使用了環境變數囉!

    例題:請在目前的 bash 環境下,再觸發一次 bash ,並以『 ps -l 』這個指令觀察程序相關的輸出資訊。
    答:
      直接執行 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 是來自於第一個所產生的嘛!

    重點來啦!所以說,在系統上面的各個程序可能是有相關性的喔! 也就是有所謂的父程序與子程序的關係~至於程序的相關性,我們可以使用 pstree 這支程式去查驗, 就能知道彼此之間的關係了。

    另外要注意的是:所謂『擒賊先擒王』, 如果哪天你一直發現『奇怪,怎麼有個程式關閉後,不久又會自動產生? 而且自動產生的 PID 還不一樣!』,呵呵!大概不需要懷疑的是,如果不是 例行性命令 的影響, 肯定有一支父程序存在,他會一直重新觸發你想要關閉的那個程序, 導致你老是關不了。那怎麼辦?不是說過擒賊先擒王嗎?關閉那支父程序啦! ^_^

    其實子程序與父程序之間的關係還挺複雜的,最大的複雜點在於程式互相之間的呼叫, 以及兩者權限的相關性!這個可能就得要您自己多多建立自己的經驗了~


  • 系統或網路服務:常駐在記憶體的程序
  • 如果就我們之前學到的一些指令資料來看,其實我們下達的指令都很簡單, 包括用 ls 顯示檔案啊、用 touch 建立檔案啊、rm/mkdir/cp/mv 等指令管理檔案啊、 chmod/chown/passwd 等等的指令來管理權限等等的,不過,這些指令都是執行完就結束了。 也就是說,該項指令被觸發後所產生的 PID 很快就會終止呢! 那有沒有一直在執行的程序啊?當然有啊!而且多的是呢!

    舉個簡單的例子來說好了,我們知道系統每分鐘都會去掃瞄 /etc/crontab 以及相關的設定檔, 來進行工作排程吧?那麼那個工作排程是誰負責的?當然不是鳥哥啊! 呵呵!是 crond 這個程式所管理的,我們將他啟動在背景當中一直持續不斷的運作, 套句以前 DOS 年代常常說的一句話,那就是『常駐在記憶體當中的程序』啦!

    這些常駐在記憶體當中的程序有很多,不過主要大致分成系統本身所需要的服務, 例如剛剛提到的 crond 及 atd ,還有 syslog 等等的。還有一些則是負責網路連線的服務, 例如 Apache, named, postfix, vsftpd... 等等的。這些網路服務比較有趣的地方, 在於這些程式被執行後,他會啟動一個可以負責網路監聽的埠口 (port) , 以提供外部用戶端 (client) 的連線要求。

    這部分我們會在認識系統服務的地方再好好的講一講, 在這裡,您先有個概念,大概知道一下,系統上面的 PID 幾乎都是透過執行一些指令所產生的, 而這些指令可能會負責一些重要的工作,例如網路伺服器啊、系統效能維持啊、 或是其他系統重要工作等等。若有興趣的話,可以先以 netstat 檢查一下您主機上的網路服務喔!

    Linux 的多人多工環境

    我們現在知道了,其實在 Linux 底下執行一個指令時,系統會給予這個動作一個 ID, 我們稱為 PID,而根據啟用這個指令的使用者與相關的指令功能,而給予這個特定 PID 一組權限, 該指令可以進行的行為則與這個 PID 的權限有關。根據這個說明,我們就可以簡單的瞭解, 為什麼 Linux 這麼多用戶,但是卻每個人都可以擁有自己的環境了吧!^_^

  • 多人環境:
  • Linux 最棒的地方就在於他的多人多工環境了!那麼,什麼是『多人多工』?!在 Linux 上面允許不同的人使用,而且每個人都有其特殊的權限,只有一個人具有至高無上的權力,那就是 root (系統管理員),除了他之外,其他人都必須要受一些限制的!而每個人進入 Linux 的環境設定都可以隨著每個人的喜好來設定 (還記得我們在 BASH 那一章提過的 ~/.bashrc 吧!?對了!就是那個光!)!現在知道為什麼了吧? 因為每個人登入後取得的 shell 的 PID 不同嘛!

  • 多工行為:
  • 我想,在某些其他作業系統中,您可能會遇到這樣的事情:『這個檔案正在使用中, 您無法開啟這個檔案!』我哩勒!還得將正在執行當中的程式關掉之後才能開這個中間暫存檔!! 而且這個時候還只有我自己一個人在使用呢~受不了~呵呵!不過, Linux 就不會這樣囉!您可以同時在不同的畫面,同時由不同的人 (當然囉,有的是經由 SSH 網路連線過來,有的是直接在螢幕前面的朋友囉!)使用『同一個檔案』, 不論是開啟或者是修改,只要您有權限,就可以使用該檔案!!

    這個東西可有用的緊!由於鳥哥是很常使用程式的 (就是 Fortran 啦,吃飯的工具!) ,而由於我們有一部主機專門用來工作的,所以配備比較高檔一點 PIII 的雙 CPU ),那麼我就可以同時的進行兩個 compiler 的程序,而且還不會互相的影響, 並且資源分配的還蠻均勻的!哈哈!怎麼會跑得這麼順暢呀!爽斃了!

    其實作業系統的多工是很複雜的行為啦!尤其涉及將多個工作直接丟給一顆 CPU 來處理~ 現在我們應該比較清楚的是,所謂的『工作』其實是將多個指令觸發成為系統程序 (PID), 而這些程序若同時被觸發時,那麼一顆 CPU 就得要同時負責許多工作了。 但我們曉得的是,並非每個程序都很耗系統資源,例如前一節提到的 crond 與 atd 這兩個系統服務, 他們並沒有消耗很多系統資源的。此時,當然囉, CPU 就可以進行其他工作, 這就是所謂的多工!

  • 多重登入環境的七個基本終端視窗:
  • 在 Linux 當中,預設提供了六個文字界面登入視窗,以及一個圖形界面,你可以使用 [Alt]+[F1].....[F7] 來切換不同的終端機界面,而且每個終端機界面的登入者還可以不同人! 很炫吧!這個東西可就很有用啦!尤其是在某個程序死掉的時候!

    其實,這也是多工環境下所產生的一個情況啦! 我們的 Linux 預設會啟動六個終端機登入環境的程式,所以我們就會有六個終端機介面。 您也可以減少啊!就是減少啟動的終端機程式就好了。詳細的資料可以先查閱 /etc/inittab 這個檔案,未來我們在開機管理流程會再仔細的介紹的!

  • 特殊的程序管理行為:
  • 以前的鳥哥笨笨的,總是以為使用 Windows 98 就可以啦!後來,因為工作的關係,需要使用 Unix 系統,想說我只要在工作機前面就好, 才不要跑來跑去的到 Unix 工作站前面去呢!所以就使用 Windows 連到我的 Unix 工作站工作!

    好死不死,我一個程序跑下來要 2~3 天,唉~偏偏常常到了第 2.5 天的時候, Windows 98 就給他掛點去!當初真的是給他怕死了~後來因為換了新電腦,用了隨機版的 Windows 2000 ,呵呵,這東西真不錯 (指對單人而言) ,在當機的時候, 他可以僅將錯誤的程序踢掉,而不干擾其他的程序進行,呵呵! 從此以後,就不用擔心會當機連連囉!不過,2000 畢竟還不夠好,因為有的時候還是會死當!!

    那麼 Linux 呢?哈哈!更棒了,幾乎可以說絕對不會當機的!因為他可以在任何時候, 將某個被困住的程序殺掉,然後在重新執行該程序而不用重新開機!夠炫吧!那麼如果我在 Linux 下以文字界面登入,在螢幕當中顯示錯誤訊息後就掛了~動都不能動,該如何是好!? 這個時候那預設的七個視窗就幫上忙啦!你可以隨意的再按  [Alt]+[F1].....[F7] 來切換到其他的終端機界面,然後以 ps -aux 找出剛剛的錯誤程序,然後給他 kill 一下,哈哈,回到剛剛的終端機界面!恩~棒!又回復正常囉!

    為什麼可以這樣做呢?我們剛剛不是提過嗎?每個程序之間可能是獨立的,也可能有相依性, 只要到獨立的程序當中,刪除有問題的那個程序,當然他就可以被系統移除掉啦!^_^

  • bash 環境下的工作管理 (job control)
  • 我們在上一個小節有提到所謂的『父程序、子程序』的關係,那我們登入 bash 之後, 就是取得一個名為 bash 的 PID 了,而在這個環境底下所執行的其他指令, 就幾乎都是所謂的子程序了。那麼,在這個單一的 bash 介面下,我可不可以進行多個工作啊? 當然可以啦!可以『同時』進行喔!舉例來說,我可以這樣做:
    [root@linux ~]# cp file1 file2 &
    
    在這一串指令中,重點在那個 & 的功能,他表示將 file1 這個檔案複製為 file2 ,且放置於背景中執行, 也就是說執行這一個命令之後,在這一個終端介面仍然可以做其他的工作!而當這一個指令 ( cp file1 file2 )執行完畢之後,系統將會在您的終端介面顯示完成的消息!很便利喔!

  • 多人多工的系統資源分配問題考慮:
  • 多人多工確實有很多的好處,但其實也有管理上的困擾,因為使用者越來越多, 將導致你管理上的困擾哩!另外,由於使用者日盛,當使用者達到一定的人數後, 通常你的機器便需要升級了,因為 CPU 的運算與 RAM 的大小可能就會不敷使用!

    舉個例子來說,鳥哥之前的網站管理的有點不太好,因為使用了一個很複雜的人數統計程式, 這個程式會一直去取用 MySQL 資料庫的資料,偏偏因為流量大,造成 MySQL 很忙碌。 在這樣的情況下,當鳥哥要登入去寫網頁資料,或者要去使用討論區的資源時, 哇!慢的很!簡直就是『龜速』啊!後來終於將這個程式停止不用了, 以自己寫的一個小程式來取代,呵呵!這樣才讓 CPU 的負載 (loading) 整個降下來~ 用起來順暢多了! ^_^

    好了!廢話說完了!開始來談一談幾個常用的指令吧!

    工作管理 (job control): &, [ctrl]-z, jobs, fg, bg, kill

    這個工作管理 (job control) 是用在 bash 環境下的,也就是說:『 當我們登入系統取得 bash shell 之後,在單一終端機介面下同時進行多個工作的行為管理 』。舉例來說,我們在登入 bash 後, 想要一邊複製檔案、一邊進行資料搜尋、一邊進行編譯,還可以一邊進行 vi 程式撰寫! 當然我們可以重複登入那六個文字介面的終端機環境中,不過,能不能在一個 bash 內達成? 當然可以啊!就是使用 job control 啦! ^_^

    從上面的說明當中,您應該要瞭解的是:『進行工作管理的行為中, 其實每個工作都是目前 bash 的子程序,亦即彼此之間是有相關性的。 我們無法以 job control 的方式由 tty1 的環境去管理 tty2 的 bash !』 這個概念請您先建立起來,後續的範例介紹之後,您就會清楚的瞭解囉!

    或許你會覺得很奇怪啊,既然我可以在六個終端介面登入,那何必使用 job control 呢? 真是脫褲子放屁,多此一舉啊!不要忘記了呢,我們可以在 /etc/security/limits.conf 裡面設定使用者同時可以登入的連線數,在這樣的情況下,某些使用者可能僅能以一個連線來工作呢! 所以囉,您就得要瞭解一下這種工作管理的模式了! 此外,這個章節內容也會牽涉到很多的資料流重導向,所以,如果忘記的話, 務必回到 BASH Shell 看一看喔!

    總之,要進行 bash 的 job control 必須要注意到的限制是:
    • 程序必須來是 shell 的 child process
    • 程序不能等待 terminal/shell 的輸入(input)


  • 直接將指令丟到背景中『執行』的 & :
  • 瞎密?將某個指令『丟到背景』當中?在一個 bash 的環境下,什麼叫做『前景 (foreground) 』與『背景 (background) 』?我們先來簡單的定義一下:
    • 前景:您可以控制的這個工作稱為前景的工作 (foreground);
    • 背景:在記憶體內可以自行運作的工作,您無法直接控制他,除非以 bg/fg 等指令將該工作呼叫出來。
    如同前面提到的,我們在只有一個 bash 的環境下,如果想要同時進行多個工作, 那麼可以將某些工作丟到背景環境當中,讓我們可以繼續操作前景的工作!那麼如何將工作丟到背景中? 最簡單的方法就是利用『 & 』這個玩意兒了!舉個簡單的例子, 我們要將 /etc/ 整個備份成為 /tmp/etc.tar.gz 時,又不想要等待, 那麼可以這樣做:
    [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 當中,當然就不會影響到我們前景的作業了。 這樣說,您應該可以更清楚資料流重導向的重要性了吧?!^_^


  • 將『目前』的工作丟到背景中『暫停』:[ctrl]-z
  • 想個情況:如果我正在使用 vi ,卻發現我有個檔案不知道放在哪裡,需要到 bash 環境下去搜尋,此時,是否要結束 vi 呢?呵呵!當然不需要啊!只要暫時將 vi 給他丟到背景當中等待即可。 例如以下的案例:
    [root@linux ~]# vi ~/.bashrc
    # 在 vi 的一般模式下,按下 [ctrl]-z 這兩個按鍵
    [1]+  Stopped                 /usr/bin/vim ~/.bashrc
    [root@linux ~]#   <==順利取得了前景的操控權!
    
    在 vi 的一般模式下,按下 [ctrl] 及 z 這兩個按鍵,螢幕上會出現 [1] ,表示這是第一個工作, 而那個 + 代表目前在背景下預設被取用的那個工作 (與 fg 這個指令有關 )! 而那個 Stopped 則代表目前這個工作的狀態。在預設的情況下,使用 [ctrl]-z 丟到背景當中的工作都是『暫停』的狀態喔!


  • 觀察目前的背景工作狀態: jobs
  • [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] 會被拿到前景當中來處理』!


  • 將背景工作拿到前景來處理:fg
  • 剛剛提到的都是將工作丟到背景當中去執行的,那麼有沒有可以將背景工作拿到前景來處理的? 有啊!就是那個 fg 啦!舉例來說,我們想要將上頭範例當中的工作拿出來處理時:
    [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 指令就能夠將背景工作拿到前景來處理囉!


  • 讓工作在背景下進行: bg
  • 我們剛剛提到,那個 [ctrl]-z 可以將目前的工作丟到背景底下去『暫停』, 那麼如何讓一個工作在背景底下『 Run 』呢?我們可以在底下這個案例當中來測試! 注意喔!底下的測試要進行的快一點!^_^
    範例一:一執行 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 囉! 看到差異點,嘿嘿!指令列最後方多了一個 & 的符號囉! 代表該工作被啟動在背景當中了啦! ^_^


  • 管理背景當中的工作: kill
  • 剛剛我們可以讓一個已經在背景當中的工作繼續工作,也可以讓該工作以 fg 拿到前景來, 那麼,如果想要將該工作直接移除呢?或者是將該工作重新啟動呢?呵呵! 這個時候就得需要給予該工作一個訊號 (signal) ,讓他知道該怎麼作才好啊! 此時, kill 這個指令就派上用場啦!
    [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 就會繼續存在檔案系統當中。 這樣您應該可以稍微分辨一下了吧?

    其實, kill 的妙用是很無窮的啦!他搭配 signal 所詳列的資訊 (用 man 7 signal 去查閱相關資料) 可以讓您有效的管理工作與程序 (Process),此外,那個 killall 也是同樣的用法! 至於常用的 signal 您至少需要瞭解 1, 9, 15 這三個 signal 的意義才好。 此外, signal 除了以數值來表示之外,也可以使用訊號名稱喔! 舉例來說,上面的範例二就是一個例子啦!至於 signal number 與名稱的對應, 呵呵,使用 kill -l 就知道啦(L的小寫)!

    程序管理

    本章一開始就提到所謂的『程序』的概念,包括程序的觸發、子程序與父程序的相關性等等, 此外,還有那個『程序的相依性』以及所謂的『殭屍程序』等等需要說明的呢! 為什麼程序管理這麼重要呢?
    • 首先,由於我們在操作系統時,各項工作其實都是經過某個 PID 來達成的, 因此,能不能進行某項工作,就與該程序的權限有關了。
    • 再來,如果您的 Linux 系統是個很忙碌的系統,那麼當整個系統資源快要被使用光時, 您是否能夠找出最耗系統的那個程序,然後刪除該程序,讓系統恢復正常呢?
    • 此外,如果由於某個程式寫的不好,導致產生一個有問題的程序在記憶體當中, 您又該如何找出他,然後將他移除呢?
    • 如果同時有五六項工作在您的系統當中運作,但其中有一項工作才是最重要的, 該如何讓那一項重要的工作被最優先執行呢?
    所以囉,一個稱職的系統管理員,必須要熟悉程序的管理流程才行,否則當系統發生問題時, 還真是很難解決問題呢!當然啦,程序的管理其實也是很難理解的部分, 尤其講到子程序與父程序之間的關係,更不容易理解。傷腦筋啊!無論如何,咱們還是得來看一看, 系統上面到底有多少程序在運作啊?

    程序的觀察

    既然程序這麼重要,那麼我們如何查閱系統上面正在運作當中的程序呢?很簡單啊! 利用靜態的 ps 或者是動態的 top,還能以 pstree 來查閱程序樹之間的關係喔!


  • ps
  • [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 就好了!

    在預設的情況下, ps 僅會列出與目前所在的 bash shell 有關的 PID 而已,所以, 當我使用 ps -l 的時候,只有三個 PID (範例一)。注意一下,我有一個 bash 的 PID , 而且也有一個 ps 的 PID ,瞭解了吧?呵呵!在 bash 裡面執行程式時,是會觸發一個新的 process 的喔!而且,兩者之間是有相關性的,看 PID 與 PPID 的號碼,你就會曉得兩者的差異了!

    那麼,什麼是『有效使用者 ID 』呢?還記得我們提過的 SUID 吧?我以 dmtsai 去執行 /usr/bin/passwd 取得的那個 process 竟然是 root 的權限喔! 此時,實際的使用者 (real user) 是 dmtsai ,但是有效的使用者 (effective user) 是 root 啦! 這樣說,可以理解吧!?

    一般來說,鳥哥會建議您,直接使用『ps aux』這個指令參數即可, 顯示的結果例如上面的範例二囉。在範例二的各個顯示項目代表的意義為:
    • USER:該 process 屬於那個使用者帳號的?
    • PID :該 process 的號碼。
    • %CPU:該 process 使用掉的 CPU 資源百分比;
    • %MEM:該 process 所佔用的實體記憶體百分比;
    • VSZ :該 process 使用掉的虛擬記憶體量 (Kbytes)
    • RSS :該 process 佔用的固定的記憶體量 (Kbytes)
    • TTY :該 process 是在那個終端機上面運作,若與終端機無關,則顯示 ?,另外, tty1-tty6 是本機上面的登入者程序,若為 pts/0 等等的,則表示為由網路連接進主機的程序。
    • STAT:該程序目前的狀態,主要的狀態有:
      • R :該程序目前正在運作,或者是可被運作;
      • S :該程序目前正在睡眠當中 (可說是 idle 狀態啦!),但可被某些訊號 (signal) 喚醒。
      • T :該程序目前正在偵測或者是停止了;
      • Z :該程序應該已經終止,但是其父程序卻無法正常的終止他,造成 zombie (疆屍) 程序的狀態
    • START:該 process 被觸發啟動的時間;
    • TIME :該 process 實際使用 CPU 運作的時間。
    • COMMAND:該程序的實際指令為何?
    我們取這一行來做個簡單的說明:
    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 這個指令啦!

    除此之外,我們必須要知道的是『疆屍 (zombie) 』程序是什麼? 通常,造成疆屍程序的成因是因為該程序應該已經執行完畢,或者是因故應該要終止了, 但是該程序的父程序卻無法完整的將該程序結束掉,而造成那個程序一直存在記憶體當中..... 如果您發現在某個程序的 CMD 後面還接上 <defunct> 時,就代表該程序是疆屍程序啦,例如:
    apache  8683  0.0  0.9 83384 9992 ?   Z  14:33   0:00 /usr/sbin/httpd <defunct>
    
    當系統不穩定的時候就容易造成所謂的疆屍程序,可能原因是因為程式寫的不好啦, 或者是使用者的操作習慣不良等等所造成。如果您發現系統中很多疆屍程序時, 呵呵!記得啊!要找出該程序的父程序,然後好好的做個追蹤,好好的進行主機的環境最佳化啊! 看看有什麼地方需要改善的,不要只是直接將他 kill 掉而已呢! 不然的話,萬一他一直產生,那可就麻煩了! @_@


  • top
  • [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 bash
    
    top 也是個挺不錯的程序觀察工具!但不同於 ps 是靜態的結果輸出, top 這個程式可以持續的監測 (monitor) 整個系統的程序工作狀態,例如上面的範例一所示啊! 在預設的情況下,每次更新程序資源的時間為 5 秒,不過,可以使用 -d 來進行修改。

    top 主要分為兩個畫面,上面的畫面為整個系統的資源使用狀態,基本上總共有六行, 顯示的內容依序是:
    • 第一行:顯示系統已啟動的時間、目前上線人數、系統整體的負載(load)。 比較需要注意的是系統的負載,三個數據分別代表 1, 5, 10 分鐘的平均負載。 一般來說,這個負載值應該不太可能超過 1 才對,除非您的系統很忙碌。 如果持續高於 5 的話,那麼.....仔細的看看到底是那個程序在影響整體系統吧!

    • 第二行:顯示的是目前的觀察程序數量,比較需要注意的是最後的 zombie 那個數值,如果不是 0 ,嘿嘿!好好看看到底是那個 process 變成疆屍了吧?!

    • 第三行:顯示的是 CPU 的整體負載,每個項目可使用 ? 查閱。需要觀察的是 id (idle) 的數值,一般來說,他應該要接近 100% 才好,表示系統很少資源被使用啊! ^_^。

    • 第四行與第五行:表示目前的實體記憶體與虛擬記憶體 (Mem/Swap) 的使用情況。

    • 第六行:這個是當在 top 程式當中輸入指令時,顯示狀態的地方。 例如範例四就是一個簡單的使用例子。
    至於 top 底下的畫面,則是每個 process 使用的資源情況。比較需要注意的是:
    • PID :每個 process 的 ID 啦!
    • USER:該 process 所屬的使用者;
    • PR :Priority 的簡寫,程序的優先執行順序,越小越早被執行;
    • NI :Nice 的簡寫,與 Priority 有關,也是越小越早被執行;
    • %CPU:CPU 的使用率;
    • %MEM:記憶體的使用率;
    • TIME+:CPU 使用時間的累加;
    一般來說,如果鳥哥想要找出最損耗 CPU 資源的那個程序時,大多使用的就是 top 這支程式啦!然後強制以 CPU 使用資源來排序 (在 top 當中按下 P 即可), 就可以很快的知道啦! ^_^。多多愛用這個好用的東西喔!


  • pstree
  • [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 就對了! ^_^

    程序的刪除

    我們在前幾個小節提到的『背景工作管理』當中提到過, 要給予某個已經存在的工作某些動作時,是直接給予一個訊號 (signal) 給該 PID 即可。 常見的工作可以使用 kill -l (L 的小寫) 來查閱!而主要的訊號代號與名稱對應及內容是:

    代號名稱內容
    1SIGHUP代表『讓該 PID 重新讀取自己的設定檔』 ,類似重新啟動
    2SIGINT代表用鍵盤輸入的 [ctrl]-c 來中斷一個程序的進行。
    9SIGKILL代表強制中斷一個程序的進行,如果該程序進行到一半, 那麼尚未完成的部分可能會有『半產品』產生,類似 vim會有 .filename.swp 保留下來。
    15SIGTERM以正常的結束程序來終止該程序。由於是正常的終止, 所以後續的動作會將他完成。不過,如果該程序已經發生問題,就是無法使用正常的方法終止時, 輸入這個 signal 也是沒有用的。

    而 kill 可以幫我們將這個 signal 傳送給某個工作 (%jobnumber) 或者是某個 PID (直接輸入數字), 也就是說, kill 後面直接加數字與加上 % 的情況是不同的!這個很重要喔!不要搞錯了。 我們就活用一下 kill 與剛剛上面提到的 ps 來做個簡單的練習吧!

    例題:以 ps 找出 syslog 這個服務的 PID 後,再使用 kill 重新讀取 syslog 的設定檔資料:
    答:
      我們可以使用底下的方式找出 syslog 的 PID 喔!
        ps aux | grep 'syslog' | grep -v 'grep'| awk '{print $2}'
      接下來,再給予 kill -SIGHUP 的訊號至該 PID ,所以,整個指令串可以這樣寫:
        kill -SIGHUP `ps aux|grep 'syslog'|grep -v 'grep'|awk '{print $2}'`
      然後立刻 tail -n 5 /var/log/messages 看看 syslog 有沒有重新被啟動啊?

    由於 kill 後面必須要加上 PID (或者是 job number),所以,通常 kill 都會配合 ps, pstree 等指令,因為我們必須要找到相對應的那個程序的 ID 嘛!但是,如此一來,很麻煩~ 有沒有可以利用『下達指令的名稱』來給予訊號的?舉例來說,能不能直接將 syslog 這個程序給予一個 SIGHUP 的訊號呢?可以的!用 killall 吧!
    [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 啟動的程序,就會通通的被刪除啦! ^_^

    系統資源的觀察

    除了系統的程序之外,我們還必須就系統的一些資源進行檢查啊! 舉例來說,我們使用 top 可以看到很多系統的資源對吧!那麼,還有沒有其他的工具可以查閱的? 當然有啊!底下這些工具指令可以玩一玩!


  • free
  • [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 則是在已被使用的量當中,用來作為緩衝及快取的量。

    仔細的看到範例一的輸出喔,我的 Linux 主機是很平凡的,根本沒有什麼工作, 但是,我的實體記憶體是幾乎被用光光的情況呢!不過,至少有 129 MB 用在緩衝記憶工作, 94 MB 則用在快取工作,也就是說,系統是『很有效率的將所有的記憶體用光光』, 目的是為了讓系統的存取效能加速啦!

    很多朋友都會問到這個問題『我的系統明明很輕鬆,為何記憶體會被用光光?』 現在瞭了吧?沒有錯!被用光是正常的!而需要注意的反而是 swap 的量。一般來說, swap 最好不要被使用,尤其 swap 最好不要被使用超過 20% 以上, 如果您發現 swap 的用量超過 20% ,那麼,最好還是買實體記憶體來插吧! 因為, Swap 的效能跟實體記憶體實在差很多,而系統會使用到 swap , 絕對是因為實體記憶體不足了才會這樣做的!如此,瞭解吧!


  • uname
  • [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 以上等級的硬體平台喔。


  • uptime
  • 這個指令很單純呢!就是顯示出目前系統已經開機多久的時間,以及 1, 5, 15 分鐘的平均負載就是了。還記得 top 吧?沒錯啦! 這個 uptime 可以顯示出 top 畫面的最上面一行!
    [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 啊!
    


  • netstat
  • 這個 netstat 也是挺好玩的,其實,這個指令比較常被用在網路的監控方面, 不過,在程序管理方面也是需要瞭解的啦!這個指令的執行如下所示:基本上, netstat 的輸出分為兩大部分,上面是網路介面相關的連線,下方則是與 unix 程序有關的項目。
    [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 的服務了。那如何關閉啊? 就關掉該程式所觸發的那個程序就好了!例如上面的範例三所提供的例子啊! ^_^


  • dmesg
  • 在開機的時候你會發現有很多的訊息出現吧,例如 CPU 的形式、硬碟、 光碟型號及硬碟分割表等等,這些資訊的產生都是核心 (kernel) 在進行硬體的測試與驅動啦。 但是訊息都是『刷』的一聲就跑過去了!完全來不及看!傷腦筋~

    這些訊息有時候對於系統管理員是很重要的,因為他提供了系統的資訊呀! 要看這些訊息你可以用 dmesg 這個指令來觀看! 因為訊息實在太多了,所以可以加入這個管線指令『 | more 』來使畫面暫停!

    範例一:輸出所有的核心開機時的資訊
    [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 試看看呢!


  • sar
  • 這個 sar 並不是系統預設的安裝套件,如果您不是選擇全部安裝的話,這個套件預設是不裝的。 不過,如果您是選擇全部安裝,嘿嘿!那就可以玩這個 sar 了。 這個 sar 的功能倒是可以玩一玩的,因為他可以在您想要主動偵測主機的資源狀態, 然後繪製成為圖表時,相當好用的一個工具喔!
    [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 的動作!參考看看先!

    關於程序的執行順序:

    還記得我們提過的多人多工環境吧?因為目前的 x86 平台的 CPU 可以做到多工的行為, 所以囉,我們的 Linux 可以在 x86 上面『同時進行多個工作』的呢!那麼多個工作是如何進行的呢? 其實每個工作都會進入到 CPU 的工作排程當中,並等待 CPU 來執行, 而 CPU 會根據每個工作的優先執行序 (priority) 來判斷誰比較重要, 所以某個工作就可能會比較優先被執行完畢啦!

    也就是說, Linux 系統中,每個 process 都會擁有一個所謂的『優先執行序 (priority)』的屬性, 利用該屬性來讓 CPU 判斷那個工作是比較重要的,那個工作在一群工作當中就會優先被執行, 也讓系統資源可以分配的更恰當。我們可以使用 ps 還觀察優先執行序:
    [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 的值,基本上,他的相關性是這樣的:
    • PRI(new) = PRI(old) + nice
    不過您要特別留意到,如果原本的 PRI 是 50 ,並不是我們給予一個 nice = 5 ,就會讓 PRI 變成 55 喔! 因為 PRI 是系統『動態』決定的,所以,雖然 nice 值是可以影響 PRI ,不過, 最終的 PRI 仍是要經過系統分析後才會決定的。另外, nice 值是有正負的喔,而既然 PRI 越小越早被執行, 所以,當 nice 值為負值時,那麼該程序就會降低 PRI 值,亦即會變的較優先被處理。此外,您必須要留意到:
    • 一般使用者的 nice 值為 0 ~ 19 ;
    • root 可用的 nice 值為 -20 ~ 19 ;
    • 一般使用者僅可將 nice 值越調越高,如果本來 nice 為 5 ,則未來僅能調整到大於 5 的 nice ;
    • 一般使用者僅能調整屬於自己的程序的 nice 值。
    這也就是說,要調整某個程序的優先執行序,就是『調整該程序的 nice 值』啦!那麼如何給予某個程序 nice 值呢?有兩種方式,分別是:
    • 一開始執行程式就立即給予一個特定的 nice 值:用 nice 指令;
    • 調整某個已經存在的 PID 的 nice 值:用 renice 指令。


  • nice
  • [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 值調大一些,可以使系統的支援分配的更為公平!


  • renice
  • [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 才行啊!

    剛好,由上面這個範例當中我們也看的出來,雖然修改的是 bash 那個 PID 為 18852 的程序, 但是該程序所觸發的 ps 指令當中的 PID 同樣的也有一個 nice = 10 的結果喔! 瞭解了吧?整個 nice 值是可以在父程序 --> 子程序之間傳遞的呢!

    另外,除了 renice 之外,其實那個 top 同樣的也是可以調整 nice 值的! top 也是可以調整已經存在的某個 process 的 nice 喔!

    特殊檔案與程序:

    我們在 檔案與目錄管理當中的 SUID/SGID/SBIT 提到這一些奇怪的特殊權限的檔案,這些檔案到底是怎麼產生特殊權限的行程?還有, 在磁碟掛載的時候,有時老是出現『 device is busy 』的字樣,真麻煩~到底是怎麼回事啊? 我們底下就來談一談。

    SUID/SGID/SBIT 的概念

    雖然已經在前面的章節提過 SUID/SGID 等等的特殊權限,但是到底他是如何產生的? 首先,我們以條列式的方法列出使用者是否能夠操作 SUID/SGID 的指令吧!
    • 關於 SUID 的執行:
      • Set UID 的權限設定值,僅對 binary file 有效;
      • 程式操作者必須要擁有該 binary file 的可執行權限 (x) ;
      • 當程式操作者執行該具有 SUID 的 binary file 時,該 binary file 所觸發的程序中, 該程序的有效使用者 (effective user) 為該 binary file 的擁有者。
    很簡單的概念吧!基本上,也就是說,使用者所觸發的 SUID 的程序中, 有效使用者會變成該 SUID 指令的程式擁有者啦!我們以 pstree 配合 passwd 來做個實驗好咯。 請您以 dmtsai 這個一般身份使用者登入後,執行 passwd ,但是先不要輸入密碼, 然後以另外一個終端機登入系統,使用 pstree -u 後,應該會看到如下的畫面喔:
    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 ) 的權限喔!這樣夠明白了吧?!

    那麼既然 SUID/SGID 的權限是比較可怕的,您該如何查詢整個系統的 SUID/SGID 的檔案呢? 應該是還不會忘記吧?使用 find 即可啊!
      find / -perm +6000

    /proc/* 代表的意義:

    其實,我們之前提到的所謂的程序都是在記憶體當中嘛!而記憶體當中的資料又都是寫入到 /proc/* 這個目錄下的,所以囉,我們當然可以直接觀察 /proc 這個目錄當中的檔案啊! 如果您觀察過 /proc 這個目錄的話,應該會發現他有點像這樣:
    [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
    .....以下省略.....
    
    裡面的資料還挺多的,不過,比較有趣的其實是兩個檔案,分別是:
    • cmdline:這個程序被啟動的指令串;
    • environ:這個程序的環境變數內容。
    很有趣吧!如果你查閱一下 cmdline 的話,就會發現:
    [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 的裝置也記錄在此喔!

    其實,上面這些檔案鳥哥在此建議您可以使用 cat 去查閱看看,不必深入瞭解, 不過,觀看過檔案內容後,畢竟會比較有感覺啦!如果未來您想要自行撰寫某些工具軟體, 那麼這個目錄底下的相關檔案可能會對您有點幫助的喔!

    查詢已開啟檔案或已執行程序開啟之檔案:

    其實還有一些與程序相關的指令可以值得參考與應用的,我們來談一談:

  • fuser
  • 如果當我們要卸載某個裝置時,他老是告訴我們『 device is busy 』, 那麼到底是那個程序在使用這個裝置呢?舉例來說,當無法 umount /home 時, 該怎麼辦?此時我們可以使用 fuser 來幫忙啦!
    [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 我們可以找出使用該檔案、 目錄的程序,藉以觀察的啦!

  • lsof
  • 相對於 fuser 是由檔案或者裝置去找出使用該檔案或裝置的程序,反過來說, 如何查出某個程序開啟或者使用的檔案與裝置呢?呼呼!那就是使用 lsof 囉~
    [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
    .....底下省略.....
    
    這個指令可以找出您想要知道的某個程序是否有啟用哪些資訊? 例如上頭提到的範例四的執行結果呢! ^_^

  • pidof
  • [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 與正規表示法, 就可以很輕易的找到您所想要的程序內容了呢。

    參考資料

    本章習題練習

    ( 要看答案請將滑鼠移動到『答:』底下的空白處,按下左鍵圈選空白處即可察看 )
    • 簡單說明什麼是程式 (program) 而什麼是程序 (process)?
      程式 (program) 是系統上面可以被執行的檔案,由於 Linux 的完整檔名 (由 / 寫起) 僅能有一個, 所以 program 的檔名具有單一性。當程式被執行後,就會啟動成程序 (process), 一個 program 可以被不同的使用者或者相同的使用者重複的執行成為多個程序, 且該程式所造成的程序還因為不同的使用者,而有不同的權限,且每個 process 幾乎都是獨立的。
    • 我今天想要查詢 /etc/crontab 與 crontab 這個程式的用法與寫法,請問我該如何線上查詢?
    • 查詢 crontab 指令可以使用 man crontab 或 info crontab ,至於查詢 /etc/crontab ,則可以使用 man 5 crontab 囉!
    • 我要如何查詢 crond 這個 daemon 的 PID 與他的 PRI 值呢?
    • ps -aux | grep crond 即可查到!
    • 我要如何修改 crond 這個 PID 的優先執行序?
    • 先以 ps -aux 找到 crond 的 PID 後,再以: renice -n number PID 來調整!
    • 我是一般身份使用者,我是否可以調整不屬於我的程序的 nice 值?此外,如果我調整了我自己的程序的 nice 值到 10 ,是否可以將他調回 5 呢?
    • 不行!一般身份使用者僅能調整屬於自己的 PID 程序,並且,只能將 nice 值一再地調高,並不能調低,所以調整為 10 之後,就不能降回 5 囉!
    • 我要怎麼知道我的網路卡在開機的過程中有沒有被捉到?
    • 可以使用 dmesg 來視察!
    修改歷史:
    • 2002/06/28:第一次完成
    • 2003/02/10:重新編排與加入 FAQ
    • 2005/09/07:將舊的文章移動到 此處
    • 2005/09/18:哈哈,終於將這篇寫完囉。新增了一些簡單的小指令啦。
    伺服器篇文件
    各版本彙整說明
    CentOS 6.x