What is a Process
執行序 (Process) 簡單說即為將指令執行後載入至記憶體 (Memory) 中稱之,而所有執行序則儲存於 /proc 中,如下練習中在 GUI 環境下執行 xclock & 將該程序丟到背景執行,系統顯示其 PID 當然您也可使用 ps 指令來查詢,而當程序執行時可看到在 /proc 中自動建立以該 PID 命名的資料夾,若關閉該執行序則相對的在 /proc 中的資料夾便立即消失 (自記憶體中釋放)。# xclock & //執行 xclock 並丟到背景執行
[1] 2996 //顯示其 PID
# ps aux |grep xclock //使用指令 ps 也可查詢其 PID
root 2996 0.1 0.7 7964 2748 pts/1 S 09:17 0:00 xclock
# ls -l /proc/2996 //查詢 /proc 資料夾下其 PID 資料夾內容可發現執行指令的絕對路徑
...略...
lrwxrwxrwx 1 root root 0 Sep 5 09:21 exe -> /usr/bin/xclock
...略...
# ls -l /proc/2996 //關閉該執行序後資料夾便立即消失 (自記憶體中釋放)
ls: /proc/2996: No such file or directory
Process State
當我們鍵入指令 ps aux 來查詢目前系統所執行的所有執行序 (Process) 我們可看到啟動該執行序的使用者 USER、PID 號碼、CPU 使用時間、Memory 使用時間 ...等,其中有一個欄為位 STAT 也就是 執行序狀態 (Process State),本節即為了解相關的縮寫意義。- S: Sleep (目前未執行但受到觸發後即轉變為 Run)。
- R: Run。
- T: 暫停 (kill -19)。
- N: 低優先權。
- D: Uninterruptable sleep (不可中斷的休眠,例如 H/W、I/O),例如執行指令 eject 退出光碟機拖盤,這是屬於硬體 I/O 也就是執行後就要做完即使是 root 也無法停止該動作的執行 (無法時拖盤退到一半時停住吧!)。
- Z: Zombie (死掉的子行程)。
- <: 高優先權。
鍵入指令 ps aux 即可查詢目前系統上所有 Process 及顯示所有欄位。
# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 2064 624 ? Ss 08:18 0:04 init [5]
...略...
若您不想查看所有欄位也可指令要顯示的欄位,請鍵入如下指令:
# ps axo pid,user,cmd,stat | head -n 6
PID USER CMD STAT
1 root init [5] Ss
2 root [migration/0] S<
3 root [ksoftirqd/0] SN
4 root [watchdog/0] S<
5 root [events/0] S<
Process Stat (Sleep、Run)
程序執行後即到此狀態,如下執行指令 xeyes & 後查看其狀態即為 Sleep,但此時程序仍為結束而是在等待觸發條件,若觸發後狀態變會轉變為 Run。# xeyes &
[1] 28350
# ps axo pid,user,cmd,stat | grep xeyes
28350 root xeyes S
Process Stat (T)
可利用指令 kill -19 command 來對指定的程序執行 暫停 的動作,若要解除對程序的暫停請使用指令 kill -18 command 來達成。# xeyes &
[1] 28350
# kill -19 28350
# ps axo pid,user,cmd,stat | grep xeyes
28350 root xeyes T
Process Stat (D, Uninterruptable sleep)
Uninterruptable sleep ,不可中斷的休眠,例如 退出光碟機拖盤因為這是屬於硬體 I/O 也就是執行後就要做完即使是 root 也無法停止該動作的執行,您可嘗試當光碟機拖盤進行退出或收回時終止該動作 (相信無法使拖盤退到一半時停住吧!),在執行退出及收回光碟機拖盤時其狀態便為 D (Uninterruptable sleep)。- eject: 退出光碟機拖盤。
- eject -r: 收回光碟機拖盤。
Process Priority (N、<)
系統的程序執行優先權數值範圍為 -20 ~ 19 而優先權數值 -20 為最高優先權數值 19 為最低,所有程序的預設優先權數值為 0,以下為 root 及一般使用者所能使用的優先權數值及程序狀態。root
- Priority Setting: -20 ~ 19
- Process State (-20 ~ 0): <
- Process State (0 ~ 19): N
non-root
- Priority Setting: 0 ~ 19
- Process State (0 ~ 19): N
從上面說明我們可了解只有 root 能設定優先權數值 -20 ~ 19 而一般使用者僅能設定優先權數值 0 ~ 19,至於如何改變優先權數值? 我們可利用指令 nice、renice。
- nice: 指定程序的優先權數值。
- renice: 改變已執行程序的優先權數值。
# nice -n 5 command //指定執行的指令優先權數值為 5
# renice 5 PID //指定正在執行中的 PID 其優先權數值為 5
# ps alx | head -n 6 //顯示 Nice 值,如下可看到 nice 值 19 其狀態為 N,而 nice 值 -5 其狀態為 <
F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND
4 0 1 0 15 0 2064 624 - Ss ? 0:05 init [5]
1 0 2 1 -100 - 0 0 migrat S< ? 0:00 [migration/0]
1 0 3 1 34 19 0 0 ksofti SN ? 0:00 [ksoftirqd/0]
5 0 4 1 -100 - 0 0 watchd S< ? 0:00 [watchdog/0]
1 0 5 1 10 -5 0 0 worker S< ? 0:03 [events/0]
Finding Processes
我們可使用指令來快速查詢哪些 Process 其 PID 及 PID Group- pidof: 查詢 command 的 PID (遠端執行會有問題)。
- pgrep: 查詢 command 的 PID Group。
# pidof bash //查詢 bash 的 PID
2629
# pgrep bash //查詢 bash 的 PID Group
2629
2888
# ps aux |grep -e 2629 -e 2888 //查詢 bash 的詳細 process 資訊
root 2629 0.0 0.3 4532 1476 pts/1 Ss+ 08:23 0:01 bash
root 2888 0.0 0.3 4532 1536 pts/2 Ss 08:46 0:01 -bash
Sending Signals to Processes
我們可利用指令 kill 來送訊號 (Signals) 給指定的程序,常用的訊號 (Signals) 如下:- -15: 結束 (預設值)。
- -9: 強制。
- -19: 暫停。
- -18: 解除暫停。
- 1: 重新讀取設定檔。
- -l: 列出所有訊號 (Signals) 數值。
Interactive Process Management Tools
在指令模式下我們可利用指令 top 來即時觀察系統程序,並可透過相關熱鍵來對指定的欄位進行排序,常用熱鍵如下:- P: 對 CPU 欄位進行排序。
- M: 對 Memory 欄位進行排序。
- T: 對 Time 欄位進行排序。
- h: 顯示幫助頁面。
- q: 離開。
在圖形模式下您可使用指令 gnome-system-monitor 來呼叫圖形介面的程序管理員。
Job Control
當您在文字模式下執行某些指令時會 佔住 您的提示字元符號 (也就無法繼續輸入指令),此時您可將該指令丟到背景執行這樣您的前景 (也就是提示字元符號) 便可繼續輸入其它指令。- &: 可於執行指令時在最後面加上此符號將該指令丟到背景執行。
- Ctrl + z: 可將目前在前景執行的工作執行暫停的動作。
- fg [%job number]: 指定 job number 回到前景工作。
- bg [%job number]: 指定 job number 丟到背景執行。
- kill [-SIGNAL] [%job number]: 指定 SIGNAL (ex. -19) 給 job number。
- jobs -l: 顯示所有背景執行的工作列表。
# lftp & //執行 lftp 並將該指令丟到背景執行
[1] 28546
# ls & //執行 lftp 並將該指令丟到背景執行
[2] 28547
# jobs -l //顯示目前所有在背景執行的工作列表
[1]- 28546 Running lftp &
[2]+ 28547 Done ls --color=tty
Scheduling a Process To Execute Later
當您需要系統在某些指定的時間 執行一次 (at) 或 定時 (crontab) 您指定的指令時即可使用 crontab、at 指令來達成。Exit Status
Process 在執行之後都會存入一個離開狀態 (exit status) 的數值,我們若在 Script 中遇到問題時可查看此離開狀態的數值藉以判斷之前的程序是否正確執行。- 0: 成功。
- 1 ~ 255: 失敗。
- $?: 取出最後一個 Process 的 Exit Status 數值。
例如 Ping www.hinet.net 若是成功的話,則輸出 $? 將為數值 0,若失敗的話則會依錯誤狀況不同而產生數值 1 ~ 255 的 Exit Status。
# ping -c3 www.hinet.net ; echo "Exit Status is $?" //執行 ping 3 次 Hinet 主機後顯示 Exit Status
PING www.hinet.net (203.66.88.89) 56(84) bytes of data.
64 bytes from www.hinet.net (203.66.88.89): icmp_seq=1 ttl=243 time=2.03 ms
64 bytes from www.hinet.net (203.66.88.89): icmp_seq=2 ttl=245 time=2.74 ms
64 bytes from www.hinet.net (203.66.88.89): icmp_seq=3 ttl=245 time=1.98 ms
--- www.hinet.net ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 1.984/2.253/2.742/0.346 ms
Exit Status is 0 //ping 成功所以顯示 Exit Status 數值為 0
Conditional Execution Operators
- &&: 簡單說此符號的功能為前一個指令執行 成功 才執行下一個指令。
- ||: 簡單說此符號的功能為二個指令只要有一個執行成功即可。
用下列表格可以清楚了解這二個符號對於指令執行的影響。
File Tests
在 Shell Script 中我們可以利用判斷式及配合相關參數來達成對某些檔案或資料夾達成判斷的目的,例如我們可利用下列簡單的 Script 來判斷指定的 Shell Script (test.sh)檔案是否存在,若存在就執行該 Script 若不存在則顯示訊息並 傳送 Exit Status 錯誤數值 1 給系統。#!/bin/sh
if [ -f ~/bin/test.sh ]; then
. ~/bin/test.sh
else
echo "The test.sh file not exists."
exit 1
fi
了解後我們應該想知道有哪些參數可以使用?
- -d: 目錄 (Directory)。
- -f: 檔案 (File exits)。
- -h: 捷徑 (Symbolic Link)。
- -r: 能否讀取檔案 (Readable by you)。
- -s: 檔案存在且不是空內容 (File exits and is not empty)。
- -w: 檔案存在且可寫入 (File exits and is writable by you)。
- -x: 檔案存在且可執行 (File exits and is executable by you)。
- -O: 檔案擁有人是不是你 (effectively owned by you)。
- -G: 你是不是屬於該郡組 (effectively owned by your group)。
- -K: Sticky。
Executable Files
若該檔案具備 執行 (x) 的權限那麼我們可打絕對路徑或相對路徑去執行,例如:# /home/user/weithenn/test.sh
# cd /home/user/weithenn
# ./test.sh
若不想給予該檔案 執行 (x) 的權限又想執行該檔案該如何達成? 下列三種方式都可達成沒有給予該檔案 執行 (x) 的權限卻可執行該檔案:
# cd /home/user/weithenn
# sh test.sh //方式一
# source test.sh //方式二
# . test.sh //方式三
Lab
Lab1. 如何防止 root 不小心執行 crontab -r 刪除所有排程?
Answer:因為在預設的情況下執行 crontab -r 會刪除所有排程且不會有任何提示,解決的方式除了定期備份 crontab 檔案之外您可在將參數 -i 寫入 alias 內,如此一來當執行 crontab -r 時系統便會出現詢問訊息來詢問您是否要刪除所有排程。
- /var/spool/cron/*: 備份 crontab file
- alias crontab='crontab -i': 為預設的 crontab 指令加上 -i 參數
我們未加上 -i 參數至別名若不小心執行到 crontab -r 時會清空 crontab 內容。
# crontab -u weithenn -l //顯示使用者 weithenn 的 crontab
01 * * * * root run-parts /etc/cron.hourly
# crontab -u weithenn -r //刪除 crontab (沒有任何提示訊息)
# crontab -u weithenn -l //crontab 內無任何資料夾 (此時/var/spool/cron/weithenn消失)
no crontab for weithenn
您可將 crontab 別名加入至 /etc/bashrc (系統 Alias) 或 ~/.bashrc (個人 Alias) 中即可。
# cat ~/.bashrc |grep crontab
alias crontab='crontab -i'
# source ~/.bashrc //重新讀取 alias 檔案,使變更生效 (或登出後登入也行)
# alias |grep crontab //查看 alias 是否將 crontab 別名設定載入
alias crontab='crontab -i'
# crontab -u weithenn -r //當要刪除使用者 weithenn 的 crontab 時會出現下列提示符號 (有效避免誤刪)
crontab: really delete weithenn's crontab?