處理程序 - 運籌帷握

at

【功能】

在指定的時間執行命令

【語法】

at [-f script] [-m] time [date] [+increment]
at -l [job...]
at -r job...

【說明】

at 指令從標準輸入讀取要執行的命令,最後以 <Ctrl-D> 鍵結束,系統會在指定的時間依序去處理使用者所要求執行的命令,且在指定時間時,使用者不必簽入系統中,at 指令會保留當時的環境變數如 umask、ulimit 及目前的工作目錄等資料。命令在執行時若無使用重新導向,則輸出的結果會以郵件方式傳送給使用者。這個指令在忙碌的系統中十分有用,例如可指定深夜使用者較少時,再要求系統處理耗時的工作。

at 指令的使用權可由超級使用者來管理,方法如下:

1.使用者的名稱有在檔案 /usr/sbin/cron.d/at.allow 中出現者才可使用 at 指令。若檔案 at.allow 不存在,只有檔案 /usr/sbin/cron.d/at.deny 存在,則是使用者名稱不在檔案 at.deny 者才可使用。
2.假設檔案 at.allow 及 at.deny 都不存在,則只有超級使用者有權力使用。若只有檔案 at.deny存在且是個空檔案,則表示系統上每一個使用者都可使用。
3.在檔案 at.allow 及 at.deny 中使用者是以每行一個名稱的方式放置,且只能由超級使用者去修改。

若使用者在下 at 命令時出現下面的訊息,即表示無權力使用:

at:you are not authorized to use at. Sorry.

在正常的情形下,下 at 命令後會印出一個工作編號(job number),這編號是一串很長的整數,代表從西元 1970 年1月1日到使用者指定處理時間之間的秒數。

time 的格式:

time 可使用下面的格式h、hh、hhmm、h:m、h:mm、hh:m、hh:mm(h 代表小時;m 代表分的一個數字)。正常是以24小時的格式,或是使用 am、pm 字串加到 time 後代表上午或下午。另外 time 也可使用下面的格式之一:

zulu 附加在 time 之後,表示 time 為格林威治時間。

noon 中午。
midnight 午夜。
now 現在(必須與 increment 配合使用),否則 at指令會回答 'too late'。

date 的格式:

月份名稱及日數 Dec 3
月份名稱、日數及年份(年份前須加上逗號) Dec 3,92
星期的名稱 Sunday
特殊名稱 today或tomorrow

若 date 省略,則 time 表示的範圍為未來的 24 小時。若年份省略,則月份表示的範圍為未來的 12 個月(例如現在是 12 月,而指定的月份是 5 月,是指明年的 5 月而非今年的 5 月)。

increment 的格式:

increment 是由數字後接 minutes、hours、days、weeks、months 或 years 所組成,另外可使用 next 在 increment 之前,代表加 1。

【選項】

選 項

說 明

-f script (file)

不必從標準輸入讀取命令,而是從檔案script 讀取。

-l [job] (list)

印出使用者所提出的工作編號或查詢指定的工作是否存在。

-m (mail)

要求 at 指令在工作結束後產生郵件給使用者,通知已完成工作,而不論執行的結果是否有輸出。

-r job (remove)

刪除由 at 指令產生的工作(一般使用者只能刪除自己所產生的工作)。

★註:選項 -f、-m 是在 SVR4 版本時才開始提供。

【範例】

1. 要求在 17:00 時執行:

$ at 1700
sort <account >account.new
<Ctrl-D>
job 720828000.a at Tue Nov 3 17:00:00 1992

1700 是指下午 5 點的時間,另一種相同的表示方法如下:

$ at 5pm

二者都是指同一個時間。

在下 at 指令後,可輸入要求指定時間執行的命令,結束時須按 <Ctrl-D> 鍵表示結束。最後 at 指令會顯示工作編號供使用者後續的管理。

到了指定的時間會自動開始執行 sort 指令,從 account檔案讀取資料,並將結果寫入 account.new 檔案。

由於無產生輸出的結果,故不會有郵件傳給使用者。若使用者要求 at 指令在處理結束後,可使用 -m 選項來要求無論是否有輸出的結果都會以郵件方式通知使用者。

2. 下面二個 at 指令是指相同的時間:

$ at now +1 day <job1
$ at now next day <job1

都是要求明天的此時開始執行 job 檔案中的指令。

3. 要求在指定的時間執行檔案 cleanup 中的指令:

$ at -f cleanup 2300 Sunday

4. 列出目前正等待執行的工作:

$ at -l
720828000.a Tue Nov 3 17:00:00 1992
720828001.a Tue Nov 3 17:00:01 1992
720844980.a Tue Nov 3 21:43:00 1992
721281600.a Sun Nov 8 23:00:00 1992

batch

【功能】

依順序執行多個命令

【語法】

batch

【說明】

在下 batch 指令後,會從標準輸入讀取要執行的命令,最後以 <Ctrl-D> 鍵結束,接著就依命令輸入的順序開始執行,而執行的輸出結果會以郵件方式傳給使用者。

這指令的功能類似於 at now 指令,因 batch 指令在輸入命令結束後才開始執行,若使用者下 at now 這個指令,則系統會告訴你時間來不及了。

【範例】

1. 要求 batch 指令依照順序執行多個命令:

$ batch
spell science > check.1
sort <check.1 >check.2
<Ctrl-D>
job 720853660.b at Wed Nov 4 00:07:40 1992

crontab

【功能】

要求系統定期執行命令

【語法】

crontab [file]
crontab -e [username]
crontab -r [username]
crontab -l [username]

【說明】

crontab 指令提供了一個十分便利的功能,可要求指定的命令定期的執行,這期間可為每年一次、每月一次甚至每小時或每分鐘執行一次,非常適合系統的管理與維護。

crontab 命令會從檔案 file 或從標準輸入(當 file 省略時)讀取指定的時間及要求執行的命令,放置到目錄 /var/spool/cron/crontabs 下屬於該使用者的 crontab 工作檔內(每個使用者僅有一個)。

注意:從標準輸入讀取時,是以 <DELETE> 鍵作結束,而不可使用 <Ctrl-D> 鍵,因 <Ctrl-D> 鍵是刪除原有的 crontab 指令的工作檔。

crontab 指令的使用權是由超級使用者來管理,方法如下:

1. 使用者的名稱有在檔案 /usr/sbin/cron.d/cron.allow 中出現者才可使用 crontab 指令,倘若是檔案 cron.allow不存在,只有檔案 /usr/sbin/cron.d/cron.deny 存在,則是使用者名稱不在檔案 cron.deny 者才可使用。
2. 假設檔案 cron.allow 及 cron.deny 都不存在,則只有超級使用者有權力使用,若只有檔案 cron.deny 存在且是個空檔案,則表示系統上每一個的使用者都可使用。
3. 在檔案 cron.allow 及 cron.deny 中的使用者是以每行一個名稱的方式放置,且只能由超級使用者去修改。

若使用者在下 crontab 命令時出現下面的訊息,即表示無權力使用:

crontab:you are not authorized to use cron. Sorry.

在正常的情形,下 crontab 命令後會印出一個工作編號(job number),這編號是一串很長的整數,代表從西元 1970 年1月1日到使用者指定處理時間之間的秒數。

file 的內容是以行為單位,每行有 6 個欄位,欄位間以空白字元或跳格字元分隔,前 5 欄是整數的欄位,用來指定時間,分別如下:

第一欄表示分(0 到 59)
第二欄表示小時(0 到 23)
第三欄表示該月的天數(1 到 31)
第四欄表示該年的月份(1 到 12)
第五欄表示星期數(0 到 6,0 是星期日)

欄位可以是用 '-' 符號連接的 2 個數字,表示一段期間的首尾,例如在第 3 欄中出現 '1-5',表示指定月份中的前 5 天,1 號到 5 號。若是數字間是用 ',' 符號連接,表示各個指定的時間,例如第 4 欄中出現 '1,4,7',是表示指定年份的 1 月、4 月及 7 月;若在欄位中出現 '*' 符號,則表示在該欄中的每一個有效值。

第 6欄(最後一欄)是指定時間所執行的命令。若行的尾端是以 '%' 符號為結束,則表示其餘的各行是做為命令的標準輸入,若檔案 file 內有 '#' 符號出現在行的最前端,則表示此行為註解行。命令在執行時,若無使用重新導向則會將輸出的結果以郵件方式傳給使用者。

在選項中只有超級使用者才可使用 -r、-l 選項來刪除或列出其他使用者的 crontab 工作檔。

【選項】

選 項

說 明

-e [username] (editor)

修改使用者在先前所輸入的 crontab 工作檔,或是建立一個空檔案。

-r [username] (remove)

刪除使用者的 crontab 工作檔。

-l [username] (list)

印出使用者的 crontab 工作檔內容。

★註:選項 -e 是在 SVR4 版本時才開始提供。

【範例】

1. 每天的 0:00各執行一次:

時間格式 0 0 * * *

2. 每個月的15號晚上8點各執行一次:

時間格式 0 20 15 * *

3. 5月到8月這段期間的1 號、11 號、21 號的中午12點各執行一次:

時間格式 0 12 1,11,21 5-8 *

4. 下面是超級使用者(root)的 crontab 檔案:

$ crontab -l
#ident "@(#)adm:root 1.1.5.1"
17 5 * * 0 /bin/su root -c "/sbin/cleanup > /dev/null"
48 11,14 * * 1-5 /bin/su uucp -c "/usr/lib/uucp/uudemon.admin
> /dev/null 2>&1"
45 23 * * * ulimit 5000; /bin/su uucp -c
"/usr/lib/uucp/uudemon.cleanup > /dev/null 2>&1"
40 * * * * /bin/su uucp -c "/usr/lib/uucp/uudemon.poll >
/dev/null"
26,56 * * * * /bin/su uucp -c "/usr/lib/uucp/uudemon.hour >
/dev/null"
0 2 * * 0,4 /etc/cron.d/logchecker

kill

【功能】

停止處理程序的執行

【語法】

kill [-signal] pid...
kill -signal -pgid...
kill -l

【說明】

kill 指令的處理方式是送一訊號到指定的處理程序,預設的訊號是編號 15 的 SIGTERM,為要求結束的訊號,若該處理程序沒有特別去處理這訊號,則會結束處理程序的執行。

signal 可使用數值或符號方式來指定,符號的名稱可從檔案 /usr/include/sys/signal.h 中找出,使用時符號前端的 'SIG' 字串可省略,其中編號 9 的 SIGKILL 是代表強迫停止執行。一般使用者只能送訊號給自己所啟動的處理程序,只有超級使用者可送訊號給其他使用者的處理程序,超級使用者須注意使用 kill 指令,因為停止系統處理程序的執行,將可能會造成檔案系統的損壞。

pid 及 pgid 是數值,分別代表訊息要送到那些處理程序。使用pid 時是指定識別碼為 pid 的處理程序;使用 pgid 時,則指每一個群處理程序識別碼為 pgid 者,若 pid 的值為 0,則表示要停止 shell 及其執行的所有處理程序,會將使用者退出系統(處理程序相對應的 pid 值可使用 ps 指令查出)。

【選項】

選 項

說 明

-l(list)

印出 signal 的符號名稱。

★註:所有的選項是在 SVR4 版本時才開始提供。

【範例】

1. 停止指定處理程序的執行:

$ sort <list >list.new &
678
$ kill -9 678

sort 指令是以幕後的處理方式進行排序,所以印出處理程序識別碼 678,kill 指令即可利用此一識別碼來要求停止執行。

2. 列出可使用 signal 的符號名稱:

$ kill -l
HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS
SEGV SYS PIPE ALRM TERM USR1 USR2 CLD PWR WINCH
URG POLL STOP TSTP CONT TTIN TTOU VTALRM PROF XCPU
XFSZ

nice

【功能】

調整處理程序在執行時的優先權

【語法】

nice [-increment] command [arguments]

【說明】

一般的使用者只能降低 command 在執行時的優先權,只有超級使用者才可提高優先權(使用負的 increment 值,如:--10)。優先權的值是從 0 到 39,0 表示優先權最高,39 表示優先權最低,而一般處理程序的預設值為 20。

increment 的值可為 1 到 19,若超過 19 則會自動設為 19,(若省略時預設值為 10)。

【傳回值】

nice 指令的傳回值是 command 執行結束後所傳回的值。

【範例】

1. 降低執行優先權:

nice ls -l

若無指定優先權的調整數值,則以預設降低 10 的方式處理。

2. 降低指定的執行優先權:

nice -19 ls -l

降低執行優先權的值為 19,若原來是 20,則降到 39。

3. 提高優先權:

nice --19 ls -l

只有超級使用者才可使用負的 increment 值。

nohupno hangup

【功能】

使一個處理程序在使用者退出(logoff)系統之後,仍能繼續執行,且使該處理程序不必理會結束訊號(quit signal)

【語法】

nohup command [arguments]

【說明】

一般的處理程序不論在幕前(foreground)或幕後(background)執行,只要提出這處理程序的使用者退出系統後,即會被中斷執行。因此才會有 nohup這個指令產生,可使 command 這個命令能持續的執行到正常的結束,而不會因使用者退出系統或是因 SIGQUIT 訊號的影響而結束。因此常使用在執行一個需要長時間去執行的程式,等下完命令後即可退出系統。

command 在執行時的輸出若無重新導向,則會寫到目前工作目錄的 nohup.out 檔案,若發現該檔無法寫入則換成到 $HOME/nohup.out 檔案。在使用 nohup 指令時,大多會在最後加上 '&' 符號使其置於幕後執行,如此系統的提示符號才會立即出現,供使用者下另外一個命令。

【範例】

1. 幕後執行:

$ nohup searchfile &
Sending output to nohup.out
216

因 searchfile 命令無使用重新導向,故輸出會送到 nohup.out 檔案內。使用者在下完 nohup 指令後即可簽退(logout)系統,而 searchfile 指令會續繼處理到結束為止。

2. 一次處理多個命令:

nohup command1;command2
nohup(command1;command2)

第一個 nohup 指令是只會對 command1 命令要求持續執行第二個 nohup 指令才是對 command1 及 command2 命令要求持續執行到結束為止。

psprocess status

【功能】

印出系統中處理程序的相關資訊

【語法】

ps [options]

【說明】

每個命令在系統中都有一個獨一無二的處理程序識別碼,依執行時的順序而從 0 開始編號到 32767,然後再從最小的可用編號循環使用,而 ps 指令可用來查出處理程序相關的資訊。在沒有選項時,預設輸出的結果是該終端機所提出處理程序的列表。每個處理程序的相關資訊包括有處理程序識別碼、終端機編號,執行的時間長度以及命令的名稱等,其他的資訊可用不同的選項來要求印出。使用 -f 選項時,ps 指令會將每個處理程序識別碼的指令及引數全部印出。

【選項】

選 項

說 明

-e (every)

印出系統中每一個處理程序的資訊。

-d

印出系統中每一個處理程序的資訊,除了 session leaders。

-a (all)

印出系統中每一個處理程序的資訊,除了 group leader 及不屬任一終端機的處理程序。

-j

印出 session 識別碼及處理程序的群識別碼。

-f (full)

印出最完整的列表。

-l (long)

印出較多的資訊。

-c

印出關於排程程序(scheduling)的特性。此選項會對 -f、-l 選項改變輸出。

-t termlist (terminal)

列出所有指定 termlist 終端機所產生的處理程序。termlist 的指定可使用完整的設備名稱,例如 tty04 或是可省略 tty 字串而以數字 04 代替。

-p proclist (process)

只列出在 proclist 中所指定處理程序識別碼的處理程序。

-u uidlist (user ID)

只列出在 uidlist 中所指定使用者識別碼或使用者名稱所產生的處理程序。

-g grplist (group ID)

只列出在 grplist 中指定群識別碼所產生的處理程序。

-s sesslist (session ID)

只列出在 sesslist 中指定 session leader 識別碼所產生的處理程序。

★註:選項 -j、-c、-s 是在 SVR4 版本時才開始提供。

下面是 ps 指令所產生欄位的標題及說明,括號內是說明那些選項會產生該項資訊。

F (l) 處理程序的相關旗標(以 16 進位表示)。
00 處理程式已終止。
01 系統的處理程序,會一直停留在主記憶內。
02 正由父處理程序追蹤。
04 父處理程序的追蹤訊號已停止。
08 處理程序現正在主記憶內。
10 處理程序現正在主記憶內,並等待別的事件完成。
S (l) 處理程序的狀態。
O 執行中,處理程序正由 CPU 執行。
S 睡眠中,處理程序為等待的狀態。
R 可執行,處理程序正在等待被 CPU執行
I IDLE,中間狀態。
Z 死亡狀態(zombie state)。
T 終止狀態。
X 正在等待主記憶的空間。
UID (f, l) 擁有該處理程序的使用者識別碼(在 -f 選項時,是印出使用者名稱)。
PID (f, l) 處理程序的識別碼。
當使用 kill 指令或是停止處理程序的執行時,必須使用到此識別碼。
PPID (f, l) 父處理程序的處理程序識別碼。
C (f, l) 排程(scheduling) 佔處理器的使用率。
CLS (f, l) 排程(scheduling) 的類別。
TS(timesharing) 分時系統的方式。
TR(real-time) 即時系統的方式。
SYS(system)系統方式。
當有使用 -c 選項時才會印出。
PRI (l) 處理程序的優先權。
使用 -c 選項時,數值愈大者表示優先權愈高;沒有使用 -c 選項時等級數值愈大者表示優先權低。
NI (l) NICE 值,表示執行的優先權大小,若使用-c 選項時不印出。
ADDR (l) 處理程序所佔用的記憶體位址。
SZ (l) 處理程序使用的記憶體大小。
WCHAN (l) 處理程序目前在等待或睡眠狀態的位址。若為空白則表該處理程序正在執行。
STIME (f) 處理程序開始執行的時間,若是 24 小時以前則以日期表示。
TTY (all) 處理程序所屬的終端機(若為 '?' 符號表示無控制的終端機)。
TIME (all) 處理程序已執行的時間長度。
COMMAND (all) 產生該處理程序時所下的指令名稱,若使用-f 選項時,引數也會印出。

若處理程序有加上 <defunct> 的字串表示該處理程序的父處理程序已經結束執行了。

【範例】

1. 檢查使用者本身有使用那些處理程序:

$ ps
PID TTY TIME COMD
179 console 0:03 sh
305 console 0:00 ps

結果有簽入時的 shell 程式及剛下的 ps 指令。

2. 將系統中每個處理程序以較完整的方式印出:

$ ps -ef

UID PID PPID C STIME TTY TIME COMD
root

0

0

0 01:57:44 ? 0:00 sched
root

1

0

0 01:57:44 ? 0:01 /sbin/init
root

2

0

0 01:57:44 ? 0:00 pageout
root

3

0

1 01:57:44 ? 0:05 fsflush
root

4

0

0 01:57:44 ? 0:00 kmdaemon
root

178

1

0 05:25:24 ? 0:00 /usr/lib/saf/sac -t 300
eric

179

1

1 05:25:25 console 0:03 -sh
root

161

1

0 05:25:19 ? 0:01 /usr/sbin/cron
root

169

1

0 05:25:22 ? 0:01 /usr/lib/lpsched
root

176

169

0 05:25:22 ? 0:00 lpNet
eric

306

176

9 05:37:02 console 0:00 ps -ef

在輸出中包含有指令名稱、執行的時間長度、終端機名稱等等,從這個列表中我們可看出處理程序識別碼(PID)為 0 的是 sched 程式,亦即 UNIX 系統開機後所執行的第一個程式,其他的 init、pageout、fsflush、kmdaemon 等程式皆是由 sched 所產生的,因此這些程式的 PPID 是 sched 的 PID 值。

3. 印出較多的資訊:

$ ps -l

F

S

UID

PID

PPID

C

PRI

NI

ADDR

SZ

WCHAN

TTY

TIME COMD

10

S

100

179

1

0

30

20

c03eb1b0

21

d10b2200

console 0:03 sh

10

O

100

310

179

19

50

20

c03eb3f0

59

console 0:00 ps

在 'S' 這一欄中可看出 ps 指令正由 CPU 執行中(O),以及 sh 指令在睡眠中(等待 CPU 的執行)。