1k likes | 1.35k Views
Shell Script 程式設計. 認識 Shell. 介於作業系統與系統核心之間的仲介程式就是所謂的「 Shell 」 ; 各種不同的作業系統都有其適用的 Shell ,常見的 Shell 包括: Bourne shell 其可執行檔名為 sh ,通常位於 /bin/sh 底下,為 UNIX 的標準配備,也是 root 所預設的 shell 。 C shell 其可執行檔名為 csh ,通常位於 /bin/csh 底下,其首創之舉為工作排程式控制,指令歷史和別名( alias )的功用
E N D
Shell Script 程式設計
認識Shell • 介於作業系統與系統核心之間的仲介程式就是所謂的「Shell」;各種不同的作業系統都有其適用的Shell,常見的Shell 包括: • Bourne shell其可執行檔名為sh,通常位於/bin/sh底下,為UNIX的標準配備,也是root所預設的shell。 • C shell其可執行檔名為csh,通常位於/bin/csh底下,其首創之舉為工作排程式控制,指令歷史和別名(alias)的功用 • Tenex C shell其可執行檔檔名為tcsh,通常位於/usr/local/bin/tcsh,tcsh基本上是建立在csh之上,改進最多的地方則是在於指令列的編輯方面 • Korn shell可執行檔檔名為ksh,其在程式的設計方面是使用Bourne shell的語法,又加上了tcsh的alias、job controll、指令列編輯等等優點 • Bourne Again shell可執行檔檔名為bash。通常放在/usr/local/bin/bash底下,基本上他是前面數種shell的融合,是GNU的產品。
認識Shell • 現今,以「Bourne Again shell」最為普遍,本書所推薦使用的Ubuntu Linux便是採用「Bourne Again shell」,其簡稱為Bash
Login vs non-login shell • Demo • Use window GUI • Use pietty
/etc/profile (login) ~/.profile (login) ~/.bash_login (login) ~/.bash_profile (login) ~/.bashrc (non-login) ~/.bash_logout (logout) ~/.bash_history (check it out …)
Force shell to read configuration file … • Use “source” command
Change Environment Variables vi .bashrc Add … export HISTSIZE=1000
前言 • 一般人熟悉的 JavaScript、VBScript 等, 都是屬於 script 語言。此種語言的特色是編寫成文字檔後, 不需要事先編譯, 而在需要執行時才直接解譯每一行程式的內容。 • 在 Linux 上的 Perl、Python 等都是這一類的語言, 而用這些語言所撰寫的程式, 則稱為 script。 • 而此處要介紹的 shell script, 是指用使用者環境 shell (例如bash) 所提供的語法, 所撰寫的 script。
前言 • 如果您時常用到相同執行順序的操作指令時, 便可將這些指令寫成 script 檔,如此往後要做同樣的事情時, 只要在指令列輸入該 script 檔名執行即可, 如此能省時省力。 • Shell script 具有接受指令列參數、使用者輸入/輸出及設定變數的能力。
前言 • 其指令可分為系統指令和 shell 指令, 其中系統指令是指 ls、cat、rm 等等我們在先前幾章己經見過的指令。而 shell 指令是指由 shell 直接解譯的指令, 通常用於 script 檔程式流程的控制, 像是分支 (case...)、迴圈 (loop...) 或判斷 (if...) 等用途。 • 由於大多數 Linux 發行版預設的 shell 為 bash, 因此本章中的介紹以 bash shell script為主。
如何判斷? • Use “type”
什麼是Shell Script 系統指令【export】即可列出當前的所有變數 • 「Shell」不僅可以下達單一的指令對於Linux 系統進行操作,例如複製檔案、刪除檔案,建立目錄等等。更可以程式化、批次化,所謂程式化便是經由程式語言的輔助,將原本複雜的、重複的系統指令綜合成批次指令,達到簡化與自動化的目的。
什麼是Shell Script • 指令【echo】及「變數名稱」亦可以直接顯示指定變數的資料值 • 預設的環境變數隨著所採用的Shell 不同將有所差異。以Bash 為例,所列出的環境變數包括:
建立及執行 Shell Script • 以一個簡單的範例, 來介紹如何建立與執行 shell script。 • 該範例會顯示目前的日期時間、執行路徑、使用者帳號及所在的目錄位置。 • 建立 Shell Script • 執行 Shell Script
建立 Shell Script • 請在文書編輯器輸入下列檔案內容, 並存檔為 showinfo:
建立 Shell Script • 測試 script 時, 不要將其檔名設為 test, 因為 test 是一個系統指令, 這可能會造成非預期的執行結果。 • 此檔中開頭的 3 行以 "#" 作為註解, 在執行時會略過。特別注意其中的第 1 行 "#!/bin/bash" 是用來指定此 script 以 bash 執行, 如果要設定以 tcsh 執行, 則應設成 "#!/bin/tcsh"。要指定執行的 shell 時, 一定要將它寫在第 1 行。如果沒有指定, 則以目前正在執行的 shell 來解譯。
建立 Shell Script • echo指令用來顯示提示訊息, 其格式為: • 其中 arg 是要顯示的訊息, 顯示多個訊息時要以空白隔開, 如果是字串則最好以雙引號 (“) 括住, 這樣子 shell 才能正確的處理。而參數 -neE 意義如下: • -n:在顯示訊息時不自動換行 (預設會自動換行)
建立 Shell Script • -e:顯示訊息時使用脫逸 (Escape) 字元。反斜線符號 "\" 為脫逸字元, 用來指示其後的字串是格式化選項。當 echo指令使用 -e 參數輸出顯示訊息時,會根據其後的選項將輸出訊息格式化, 而不會將它當成一般文字輸出。以上例而言 "\n" 會使游標在輸出後移到下一行, 而 "\c" 則使游標不會在顯示訊息後移至下一行。
建立 Shell Script • -E:顯示訊息時不使用脫逸字元。 • 例如第 4 行 "echo -n ...", 表示此行輸出後不換行。如此, 下一行的 date指令執行結果就會接在 "Date and time is:" 之後。 • 第 7 行 `whoami` 字串左右的反引號 (`) 是用做指令置換, 也就是將它所括起來的字串視為指令執行, 並將其輸出字串在原地展開。
建立 Shell Script • 第 4 行也可以改成和第 7 行相同的寫法:echo -e "Date and time is: `date` \n", 其意義是一樣的, 只是寫法不同。 • 而第 8、9 行, 則又是效果相同的第 3 種寫法:第 8 行 "echo -e....\c" 亦表示此行輸出後不換行, 故下一行的 pwd指令執行結果就會接在 "Your current directory is:" 之後。
執行 Shell Script • 執行 shell script 的方式有 2 種, 一種是執行 shell 程式, 並將該 script 當作參數傳給它, 指令格式如下: • 另一種方式是在指令列下直接輸入 script 檔名執行。以這種方式執行時, 必須先將檔案權限更改成可執行的權限, 否則在執行時系統將會回應 "Permission denied"的訊息。
執行 Shell Script • 要設定檔案擁有者本身執行的權限, 可用下面的指令: • 若要讓所有的使用者都可以執行此 shell script, 則可以執行 chmod a+x filename指令。 • 其中參數 "u" 是代表設定檔案擁有者本身的權限, 而 "+x" 則代表設定具有執行 (eXecute) 的權限。
執行 Shell Script • 接著我們先修改剛剛建立的 showinfo 檔的權限, 並執行看看其結果為何:
command not found • 直接執行 shell script 時, 比較常出現的問題是找不到指令, 其錯誤訊息類似下面這樣:
command not found • 出現此訊息的原因多半是沒有正確設定路徑, 請執行 export PATH=$PATH:.指令 ( 最後面是一個冒號加一個句點 ) , 將目前的工作目錄加入PATH 環境變數中即可。 • 或者在 ~/.bash_profile (.profile) 檔中增加執行路徑, 例如:
設定與取用變數的方法 • 所謂變數, 就是可存放資料的識別符號。例如 x=10, x是個變數名稱, 10則為存放的資料。在 shell script 中設定與取用變數的方法有底下幾種, 在本節中將分別說明: • 直接設定變數值 • 由指令置換取得 • 由指令列參數取得 • 由環境變數取得 • 由使用者輸入
直接設定變數值 • 設定變數的方法很簡單, 只要直接指定其值即可, 例如我們可以建立一個filename 變數存放檔名, 建立一個 user_age 變數存放使用者的年齡。 • 底下範例是設定 5000 給 money 這個變數:
直接設定變數值 • 要取用變數值的時候, 則應於變數名稱前加上 "$" 符號, 下例將顯示 money 的變數值: • 如果想在顯示的數字前加上錢字號 "$", 則必須使用脫逸字元, 例如:
由指令置換結果取得變數值 • 所謂指令置換的方式, 簡單的說, 就是把指令執行的結果設定為某一個變數的變數值。就如先前面我們曾提到的, 反引號 (`) 及 $(command) 可用來將指令的輸出視為字串, 因此我們可以利用此功能來設定變數值, 底下範例設定變數 now 的值為目前系統的時間:
使用指令列參數 • 當我們執行 script 檔時, 可以加上一些參數傳入 script 中運算。以下變數即可用以讀取從指令列所輸入的參數:
使用指令列參數 • 當某一個參數包含空白符號時, 應將此參數以雙引號括起來。 • 以下這段程式會顯示所有參數及其總數。筆者將其存為 showarg 檔:
使用指令列參數 • 然後執行 chmod +x showarg指令改為可執行, 以下為執行結果:
使用環境變數 • 系統中有許多內定的環境變數, 也有許多由其他程式所輸出 (export) 的環境變數, 這些變數也可以在 script 檔中直接取用。 • 底下範例顯示所在的目錄:
由使用者輸入 • 使用 read指令可以直接讀取使用者的輸入作為變數值, 可以用來撰寫對話式的 shell script。以下範例會先列出要求輸入使用者姓名的字串, 待使用者輸入姓名後, 將輸入的字串讀入並設定為 my_name 變數的值, 使用者輸入完並按下 [Enter] 鍵後, 顯示 "My name is" 及 my_name 變數的值 (即使用者輸入的字串):
由使用者輸入 • 修改檔案權限後即可執行, 以下為執行結果:
建構 Shell Script • 條件測試與運算式 • 程式流程控制 • 移動輸入參數 • 定義及使用函數
條件測試與運算式 • test指令用來判斷運算式的真假 (True 或 False), 其語法為: • test指令還有另外一種表達方式, 即是以中括號括住所要判斷的運算式, 如 "[ 運算式 ]"。使用這種表達方式時, 於運算式前不必加上 "test" 識別字。請在指令列執行以下範例 (等號兩邊要有一個空格): man test
條件測試與運算式 • test指令常用於 if 及 while 敘述等迴圈結束條件的測試, 它能測試的運算式可分成 『字串』、『數值』、『檔案』 與 『邏輯』 等 4 類。每一類的運算式各有其適用的運算子, 以下分項列表說明。
條件測試與運算式 • 字串運算子 • 數值運算子 • 檔案運算子 • 邏輯運算子
字串運算子 • 字串運算子用來判斷字串運算式的真偽。可用的運算子如下表:
字串運算子 • 字串運算子不可使用萬用字元, 同時應注意運算子的左右需留空白。 • 以下為執行範例:
數值運算子 • 數值運算子用來判斷數值運算式的真偽。 • 可用的運算子如下表 (其中 int1及 int2 為整數):
數值運算子 • 如果您將數值運算子用於一般字串, 將得到錯誤訊息。以下為執行範例:
檔案運算子 • 檔案運算子用來判斷檔案是否存在, 以及檔案形態和屬性。可用的運算子如下表: -d file -f file -s file -r file -w file -x file
檔案運算子 • 以下為執行範例:
邏輯運算子 • 邏輯運算子用來結合運算式或取得運算式的相反值。可用的運算子如下表:
邏輯運算子 • 以下為執行範例: