歡迎您光臨本站 註冊首頁

Linux循序漸進(12)

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0
第十一課 進程管理及作業控制(1)  

Linux是一個多任務的操作系統,系統上同時運行著多個進程,正在執行的一個或多個相關進程稱為一個作業.使用作業控制,用戶可以同時運行多個作業,並在需要時在作業之間進行切換.本章詳細介紹進程管理及作業控制的命令,包括啟動進程、查看進程、調度作業的命令.

進程及作業的概念


Linux是一個多用戶多任務的操作系統.多用戶是指多個用戶可以在同一時間使用計算機系統;多任務是指Linux可以同時執行幾個任務,它可以在還未執行完一個任務時又執行另一項任務.

操作系統管理多個用戶的請求和多個任務.大多數系統都只有一個CPU和一個主存,但一個系統可能有多個二級存儲磁碟和多個輸入/輸出設備.操作系統管理這些資源並在多個用戶間共享資源,當您提出一個請求時,給您造成一種假象,好象系統只被您獨自佔用.而實際上操作系統監控著一個等待執行的任務隊列,這些任務包括用戶作業、操作系統任務、郵件和列印作業等.操作系統根據每個任務的優先順序為每個任務分配合適的時間片,每個時間片大約都有零點幾秒,雖然看起來很短,但實際上已經足夠計算機完成成千上萬的指令集.每個任務都會被系統運行一段時間,然後掛起,系統轉而處理其他任務;過一段時間以後再回來處理這個任務,直到某個任務完成,從任務隊列中去除.

Linux系統上所有運行的東西都可以稱之為一個進程.每個用戶任務、每個系統管理守護進程,都可以稱之為進程.Linux用分時管理方法使所有的任務共同分享系統資源.我們討論進程的時候,不會去關心這些進程究竟是如何分配的,或者是內核如何管理分配時間片的,我們所關心的是如何去控制這些進程,讓它們能夠很好地為用戶服務.



進程的一個比較正式的定義是:在自身的虛擬地址空間運行的一個單獨的程序.進程與程序是有區別的,進程不是程序,雖然它由程序產生.程序只是一個靜態的指令集合,不佔系統的運行資源;而進程是一個隨時都可能發生變化的、動態的、使用系統運行資源的程序.而且一個程序可以啟動多個進程.

Linux操作系統包括三種不同類型的進程,每種進程都有自己的特點和屬性.

 

交互進程——由一個shell啟動的進程.交互進程既可以在前台運行,也可以在後台運行.
批處理進程——這種進程和終端沒有聯繫,是一個進程序列.
監控進程(也稱守護進程)——Linux系統啟動時啟動的進程,並在後台運行.
上述三種進程各有各的作用,使用場合也有所不同.

進程和作業的概念也有區別.一個正在執行的進程稱為一個作業,而且作業可以包含一個或多個進程,尤其是當使用了管道和重定向命令.例如「nroff -man ps.1|grep kill|more」這個作業就同時啟動了三個進程.

作業控制指的是控制正在運行的進程的行為.比如,用戶可以掛起一個進程,等一會兒再繼續執行該進程.shell將記錄所有啟動的進程情況,在每個進程過程中,用戶可以任意地掛起進程或重新啟動進程.作業控制是許多shell(包括bash和tcsh)的一個特性,使用戶能在多個獨立作業間進行切換.

一般而言,進程與作業控制相關聯時,才被稱為作業.

在大多數情況下,用戶在同一時間只運行一個作業,即它們向shell鍵入的命令.但是使用作業控制,用戶可以同時運行多個作業,並在需要時在這些作業間進行切換.這會有什麼用途呢?例如,當用戶編輯一個文本文件,並需要中止編輯做其他事情時,利用作業控制,用戶可以讓編輯器暫時掛起,返回shell提示符開始做其他的事情.其他事情做完以後,用戶可以重新啟動掛起的編輯器,返回到剛才中止的地方,就象用戶從來沒有離開編輯器一樣.這只是一個例子,作業控制還有許多其他實際的用途.



啟動進程

鍵入需要運行的程序的程序名,執行一個程序,其實也就是啟動了一個進程.在Linux系統中每個進程都具有一個進程號,用於系統識別和調度進程.啟動一個進程有兩個主要途徑:手工啟動和調度啟動,後者是事先進行設置,根據用戶要求自行啟動.

手工啟動

由用戶輸入命令,直接啟動一個進程便是手工啟動進程.但手工啟動進程又可以分為很多種,根據啟動的進程類型不同、性質不同,實際結果也不一樣,下面分別介紹.

1. 前台啟動

這或許是手工啟動一個進程的最常用的方式.一般地,用戶鍵入一個命令「ls –l」,這就已經啟動了一個進程,而且是一個前台的進程.這時候系統其實已經處於一個多進程狀態.或許有些用戶會疑惑:我只啟動了一個進程而已.但實際上有許多運行在後台的、系統啟動時就已經自動啟動的進程正在悄悄運行著.還有的用戶在鍵入「ls –l」命令以後趕緊使用「ps –x」查看,卻沒有看到ls進程,也覺得很奇怪.其實這是ls這個進程結束太快,使用ps查看時該進程已經執行結束了.如果啟動一個比較耗時的進程:

find / -name fox.jpg

然後再把該進程掛起,使用ps查看,就會看到一個find進程在裡面.

 

 

2. 後台啟動

直接從後台手工啟動一個進程用得比較少一些,除非是該進程甚為耗時,且用戶也不急著需要結果的時候.假設用戶要啟動一個需要長時間運行的格式化文本文件的進程.為了不使整個shell在格式化過程中都處於「癱瘓」狀態,從後台啟動這個進程是明智的選擇.

[例1]

$ troff –me notes > note_form &

[1] 4513

$

由上例可見,從後台啟動進程其實就是在命令結尾加上一個&號.鍵入命令以後,出現一個數字,這個數字就是該進程的編號,也稱為PID,然後就出現了提示符.用戶可以繼續其他工作.



上面介紹了前、後台啟動的兩種情況.實際上這兩種啟動方式有個共同的特點,就是新進程都是由當前shell這個進程產生的.也就是說,是shell創建了新進程,於是就稱這種關係為進程間的父子關係.這裡shell是父進程,而新進程是子進程.一個父進程可以有多個子進程,一般地,子進程結束后才能繼續父進程;當然如果是從後台啟動,那就不用等待子進程結束了.

一種比較特殊的情況是在使用管道符的時候.例如:

nroff -man ps.1|grep kill|more

這時候實際上是同時啟動了三個進程.請注意是同時啟動的,所有放在管道兩邊的進程都將被同時啟動,它們都是當前shell的子程序,互相之間可以稱為兄弟進程.

以上介紹的是手工啟動進程的一些內容,作為一名系統管理員,很多時候都需要把事情安排好以後讓其自動運行.管理員不是機器,也有離開的時候,有些必須要做的工作而恰好管理員不能親自操作,這時候就需要使用調度啟動進程了.

調度啟動

有時候需要對系統進行一些比較費時而且佔用資源的維護工作,這些工作適合在深夜進行,這時候用戶就可以事先進行調度安排,指定任務運行的時間或者場合,到時候系統會自動完成這一切工作.

要使用自動啟動進程的功能,就需要掌握以下幾個啟動命令.

at命令

用戶使用at命令在指定時刻執行指定的命令序列.也就是說,該命令至少需要指定一個命令、一個執行時間才可以正常運行.at命令可以只指定時間,也可以時間和日期一起指定.需要注意的是,指定時間有個系統判別問題.比如說:用戶現在指定了一個執行時間:凌晨3:20,而發出at命令的時間是頭天晚上的20:00,那麼究竟是在哪一天執行該命令呢?如果用戶在3:20以前仍然在工作,那麼該命令將在這個時候完成;如果用戶3:20以前就退出了工作狀態,那麼該命令將在第二天凌晨才得到執行.下面是at命令的語法格式:



at [-V] [-q 隊列] [-f 文件名] [-mldbv] 時間

at -c 作業 [作業...]

at允許使用一套相當複雜的指定時間的方法,實際上是將POSIX.2標準擴展了.它可以接受在當天的hh:mm(小時:分鐘)式的時間指定.如果該時間已經過去,那麼就放在第二天執行.當然也可以使用midnight(深夜),noon(中午),teatime(飲茶時間,一般是下午4點)等比較模糊的詞語來指定時間.用戶還可以採用12小時計時制,即在時間後面加上AM(上午)或者PM(下午)來說明是上午還是下午.

也可以指定命令執行的具體日期,指定格式為month day(月 日)或者mm/dd/yy(月/日/年)或者dd.mm.yy(日.月.年).指定的日期必須跟在指定時間的後面.

上面介紹的都是絕對計時法,其實還可以使用相對計時法,這對於安排不久就要執行的命令是很有好處的.指定格式為:now count time-units ,now就是當前時間,time-units是時間單位,這裡可以是 minutes(分鐘)、hours(小時)、days(天)、weeks(星期).count是時間的數量,究竟是幾天,還是幾小時,等等.

還有一種計時方法就是直接使用today(今天)、tomorrow(明天)來指定完成命令的時間.下面通過一些例子來說明具體用法.

[例2] 指定在今天下午5:30執行某命令.假設現在時間是中午12:30,1999年2月24日,其命令格式如下:

at 5:30pm

at 17:30

at 17:30 today

at now 5 hours

at now 300 minutes

at 17:30 24.2.99

at 17:30 2/24/99

at 17:30 Feb 24

 

以上這些命令表達的意義是完全一樣的,在安排時間的時候完全可以根據個人喜好和具體情況自由選擇.一般採用絕對時間的24小時計時法可以避免由於用戶自己的疏忽造成計時錯誤的情況發生,例如上例可以寫成:



at 17:30 2/24/99

這樣非常清楚,而且別人也看得懂.

對於at命令來說,需要定時執行的命令是從標準輸入或者使用-f選項指定的文件中讀取並執行的.如果at命令是從一個使用su命令切換到用戶shell中執行的,那麼當前用戶被認為是執行用戶,所有的錯誤和輸出結果都會送給這個用戶.但是如果有郵件送出的話,收到郵件的將是原來的用戶,也就是登錄時shell的所有者.

[例3]

$ at -f work 4pm 3 days

在三天後下午4點執行文件work中的作業.

$ at -f work 10am Jul 31

在7月31日上午10點執行文件work中的作業.

在任何情況下,超級用戶都可以使用這個命令.對於其他用戶來說,是否可以使用就取決於兩個文件:/etc/at.allow和/etc/at.deny.如果/etc/at.allow文件存在的話,那麼只有在其中列出的用戶才可以使用at命令;如果該文件不存在,那麼將檢查/etc/at.deny文件是否存在,在這個文件中列出的用戶均不能使用該命令.如果兩個文件都不存在,那麼只有超級用戶可以使用該命令;空的/etc/at.deny文件意味著所有的用戶都可以使用該命令,這也是默認狀態.

下面對命令中的參數進行說明.

-V 將標準版本號列印到標準錯誤中.

-q queue 使用指定的隊列.隊列名稱是由單個字母組成,合法的隊列名可以由a-z或者A-Z.a隊列是at命令的默認隊列.

-m 作業結束后發送郵件給執行at命令的用戶.

-f file 使用該選項將使命令從指定的file讀取,而不是從標準輸入讀取.

-l atq命令的一個別名.該命令用於查看安排的作業序列,它將列出用戶排在隊列中的作業,如果是超級用戶,則列出隊列中的所有工作.

命令的語法格式如下:

atq [-V] [-q 隊列] [-v]



-d atrm 命令的一個別名.該命令用於刪除指定要執行的命令序列,語法格式如下:

atrm [-V] 作業 [作業...]

-c 將命令行上所列的作業送到標準輸出.

[例4] 找出系統中所有以txt為後綴名的文件,並且進行列印.列印結束后給用戶foxy發出郵件通知取件.指定時間為十二月二十五日凌晨兩點.

鍵入:

$ at 2:00 12/25/99

然後系統出現at>提示符,等待用戶輸入進一步的信息,也就是需要執行的命令序列:

at> find / -name 「*.txt」|lpr

at> echo 「foxy:All texts have been printed.You can take them over.Good day!River」 |mail -s 」job done」 foxy

輸入完每一行指令然後回車,所有指令序列輸入完畢后,使用組合鍵結束at命令的輸入.這時候屏幕將出現如下信息:

warning:command will be executed using /bin/sh.

job 1 at 1999-12-25 02:00

提醒用戶將使用哪個shell來執行該命令序列.

實際上如果命令序列較長或者經常被執行的時候,一般都採用將該序列寫到一個文件中,然後將文件作為at命令的輸入來處理.這樣不容易出錯.

 

[例5] 上面的例子可以修改如下:

將命令序列寫入到文件/tmp/printjob,語句為:

$ at -f /tmp/printjob 2:00 12/25/99

這樣一來,at命令將使用文件中的命令序列,屏幕顯示如下:

Warning:command will be executed using /bin/sh.

job 2 at 1999-12-25 02:00

當然也可以採用以下命令:

$ at< /tmp/printjob 2:00 12/25/99

來完成同樣的任務.也就是使用輸入重定向的辦法將文件定向為命令輸入.

batch命令

batch 用低優先順序運行作業,該命令幾乎和at命令的功能完全相同,唯一的區別在於,at命令是在指定時間,很精確的時刻執行指定命令;而batch卻是在系統負載較低,資源比較空閑的時候執行命令.該命令適合於執行佔用資源較多的命令.



batch命令的語法格式也和at命令十分相似,即

batch [-V] [-q 隊列] [-f 文件名] [-mv] [時間]

具體的參數解釋請參考at命令.一般地說,不用為batch命令指定時間參數,batch本身的特點就是由系統決定執行任務的時間,如果用戶再指定一個時間,就失去了本來的意義.

[例6] 使用例4,鍵入:

$ batch

at> find / -name *.txt|lpr

at> echo 「foxy:All texts have been printed.You can take them over.Good day!River」 |mail -s 」job done」 foxy

現在這個命令就會在合適的時間進行了,進行完後會發回一個信息.

仍然使用組合鍵來結束命令輸入.而且batch和at命令都將自動轉入後台,啟動的時候也不需要加上&符號.

cron命令

前面介紹的兩條命令都會在一定時間內完成一定任務,但是要注意它們都只能執行一次.也就是說,當指定了運行命令后,系統在指定時間完成任務,一切就結束了.但是在很多時候需要不斷重複一些命令,比如:某公司每周一自動向員工報告頭一周公司的活動情況,這時候就需要使用cron命令來完成任務了.

實際上,cron命令是不應該手工啟動的.cron命令在系統啟動時就由一個shell腳本自動啟動,進入後台(不需要使用&符號).一般的用戶沒有運行該命令的許可權,雖然超級用戶可以手工啟動cron,不過還是建議將其放到shell腳本中由系統自行啟動.

cron命令會搜索/var/spool/cron目錄,尋找以/etc/passwd文件中的用戶名命名的crontab文件,被找到的這種文件將載入內存.例如一個用戶名為foxy的用戶,它所對應的crontab文件就應該是/var/spool/cron/foxy.也就是說,以該用戶命名的crontab文件存放在/var/spool/cron目錄下面.cron命令還將搜索/etc/crontab文件,這個文件是用不同的格式寫成的.



cron啟動以後,它將檢查是否有用戶設置了crontab文件,如果沒有就轉入「休眠」狀態,釋放系統資源.該後台進程佔用資源極少.它每分鐘「醒」過來一次,查看當前是否有需要運行的命令.命令執行結束后,任何輸出都將作為郵件發送給crontab的所有者,或者是/etc/crontab文件中MAILTO環境變數中指定的用戶.

上面簡單介紹了一些cron的工作原理,但是cron命令的執行不需要用戶干涉;需要用戶修改的是crontab中要執行的命令序列,下面介紹crontab命令.

crontab命令

crontab命令用於安裝、刪除或者列出用於驅動cron後台進程的表格.也就是說,用戶把需要執行的命令序列放到crontab文件中以獲得執行.每個用戶都可以有自己的crontab文件.下面就來看看如何創建一個crontab文件.

在/var/spool/cron下的crontab文件不可以直接創建或者直接修改.crontab文件是通過crontab命令得到的.現在假設有個用戶名為foxy,需要創建自己的一個crontab文件.可以使用任何文本編輯器建立一個新文件,然後向其中寫入需要運行的命令和要定期執行的時間.

然後存檔退出.假設該文件為/tmp/test.cron.再后就是使用crontab命令來安裝這個文件,使之成為該用戶的crontab文件.鍵入:

crontab test.cron

這樣一個crontab 文件就建立好了.可以轉到/var/spool/cron目錄下面查看,發現多了一個foxy文件.這個文件就是所需的crontab 文件.用more命令查看該文件的內容可以發現文件頭有三行信息:

#DO NOT EDIT THIS FILE -edit the master and reinstall.

#(test.cron installed on Mon Feb 22 14:20:20 1999)

#(cron version --$Id:crontab.c,v 2.13 1994/01/17 03:20:37 vivie Exp $)

大概意思是:

#切勿編輯此文件——如果需要改變請編輯源文件然後重新安裝.



#test.cron文件安裝時間:14:20:20 02/22/1999

如果需要改變其中的命令內容時,還是需要重新編輯原來的文件,然後再使用crontab命令安裝.

可以使用crontab命令的用戶是有限制的.如果/etc/cron.allow文件存在,那麼只有其中列出的用戶才能使用該命令;如果該文件不存在但cron.deny文件存在,那麼只有未列在該文件中的用戶才能使用crontab命令;如果兩個文件都不存在,那就取決於一些參數的設置,可能是只允許超級用戶使用該命令,也可能是所有用戶都可以使用該命令.

crontab命令的語法格式如下:

crontab [-u user] file

crontab [-u user]{-l|-r|-e}

 

第一種格式用於安裝一個新的crontab 文件,安裝來源就是file所指的文件,如果使用「-」符號作為文件名,那就意味著使用標準輸入作為安裝來源.

-u 如果使用該選項,也就是指定了是哪個具體用戶的crontab 文件將被修改.如果不指定該選項,crontab 將默認是操作者本人的crontab ,也就是執行該crontab 命令的用戶的crontab 文件將被修改.但是請注意,如果使用了su命令再使用crontab 命令很可能就會出現混亂的情況.如果是使用了su命令,最好使用-u選項來指定究竟是哪個用戶的crontab文件.

-l 在標準輸出上顯示當前的crontab.

-r 刪除當前的crontab文件.

-e 使用VISUAL或者EDITOR環境變數所指的編輯器編輯當前的crontab文件.當結束編輯離開時,編輯后的文件將自動安裝.

[例7]

# crontab -l #列出用戶目前的crontab.

10 6 * * * date

0 */2 * * * date

0 23-7/2,8 * * * date

#

在crontab文件中如何輸入需要執行的命令和時間.該文件中每行都包括六個域,其中前五個域是指定命令被執行的時間,一個域是要被執行的命令.每個域之間使用空格或者製表符分隔.格式如下:



minute hour day-of-month month-of-year day-of-week commands

第一項是分鐘,第二項是小時,第三項是一個月的第幾天,第四項是一年的第幾個月,第五項是一周的星期幾,第六項是要執行的命令.這些項都不能為空,必須填入.如果用戶不需要指定其中的幾項,那麼可以使用*代替.*是統配符,可以代替任何字元,就可以認為是任何時間,也就是該項被忽略了.在表4-1中給出了每項的合法範圍.

 

表4-1 指定時間的合法範圍

時間
合法值

minute
00-59

hour
00-23,其中00點就是晚上12點

day-of-month
01-31

month-of-year
01-12

day-of-week
0-6,其中周日是0


 

這樣用戶就可以往crontab 文件中寫入無限多的行以完成無限多的命令.命令域中可以寫入所有可以在命令行寫入的命令和符號,其他所有時間域都支持列舉,也就是域中可以寫入很多的時間值,只要滿足這些時間值中的任何一個都執行命令,每兩個時間值中間使用逗號分隔.

[例8]

5,15,25,35,45,55 16,17,18 * * * command

這就是表示任意天任意月,其實就是每天的下午4點、5點、6點的5 min、15 min、25 min、35 min、45 min、55 min時執行命令.

[例9] 在每周一,三,五的下午3:00系統進入維護狀態,重新啟動系統.那麼在crontab 文件中就應該寫入如下欄位:

00 15 * * 1,3,5 shutdown -r 5

然後將該文件存檔為foxy.cron,再鍵入crontab foxy.cron安裝該文件.

[例10] 每小時的10分,40分執行用戶目錄下的innd/bbslin這個指令:

10,40 * * * * innd/bbslink

[例11] 每小時的1分執行用戶目錄下的bin/account這個指令:

1 * * * * bin/account

[例12] 每天早晨三點二十分執行用戶目錄下如下所示的兩個指令(每個指令以;分隔):



20 3 * * * (/bin/rm -f expire.ls logins.bad;bin/expire>expire.1st)

[例13] 每年的一月和四月,4號到9號的3點12分和3點55分執行/bin/rm -f expire.1st這個指令,並把結果添加在mm.txt這個文件之後(mm.txt文件位於用戶自己的目錄位置).

12,55 3 4-9 1,4 * /bin/rm -f expire.1st>>mm.txt

[例14] 我們來看一個超級用戶的crontab文件:

#Run the 『atrun』 program every minutes

#This runs anything that』s due to run from 『at』.See man 『at』 or 『atrun』.

0,5,10,15,20,25,30,35,40,45,50,55 * * * * /usr/lib/atrun

40 7 * * * updatedb

8,10,22,30,39,46,54,58 * * * * /bin/sync

進程的掛起及恢復命令bg、fg

作業控制允許將進程掛起並可以在需要時恢復進程的運行,被掛起的作業恢復后將從中止處開始繼續運行.只要在鍵盤上按,即可掛起當前的前台作業.

[例15]

$ cat > text.file



[1] stopped cat > text.file

$ jobs

[1] stopped cat > text.file

在鍵盤上按后,將掛起當前執行的命令cat.使用jobs命令可以顯示shell的作業清單,包括具體的作業、作業號以及作業當前所處的狀態.

恢復進程執行時,有兩種選擇:用fg命令將掛起的作業放回到前台執行;用bg命令將掛起的作業放到後台執行.

[例16] 用戶正在使用Emacs,突然需要查看系統進程情況.就使用組合鍵將Emacs進程掛起,然後使用bg命令將其在後台啟動,這樣就得到了前台的操作控制權,接著鍵入「ps –x」查看進程情況.查看完畢后,使用fg命令將Emacs帶回前台運行即可.其命令格式為:



$ bg emacs

$ ps –x

$ fg emacs

默認情況下,fg和bg命令對最近停止的作業進行操作.如果希望恢復其他作業的運行,可以在命令中指定要恢復作業的作業號來恢復該作業.例如:



$ fg 1

cat > text.file

靈活使用上述命令,將給自己帶來很大的方便.




[火星人 ] Linux循序漸進(12)已經有598次圍觀

http://coctec.com/docs/linux/show-post-57604.html