# 第四堂課,因為有人要我上apcs所以繼續來說linux 上次下課之後我朋友Jason過來跟我說他覺得我的課太廢了,希望我能改上程式語言。而實際上我看了自己上個禮拜上的東西後也覺得有點廢,所以今天就讓我們來上更加進階、有趣的bash和shell script吧! ## Bash是什麼 全名為Bourne-Again SHell,Bash是一個命令處理器,通常執行於文字窗口中,並能執行使用者直接輸入的命令。Bash還能從檔案中讀取命令,這樣的檔案稱為指令碼。 在第一堂課我們說過「Linux內核是整個作業系統的核心,負責管理軟體發出的資料I/O(輸入與輸出)。它會作為電腦上硬體與軟體的橋樑」那麼要如何與內核溝通呢?就必須要透過Shell了! shell這個英文字比起想像它是一個殼層,想像它是馬力歐賽車里的烏龜殼可能還更適合。shell裡面裝著我們所打的指令,就這樣滾進又滾出內核,差不多就是這樣。 ## shell script呢? 而shell script就是由一堆bash指令加上一些判斷試與迴圈的執行檔,但也可以當作是一個小程式了 比如說我寫了個virc.sh: ``` [john@ethernet Desktop]$ sh virc.sh #在子程序中打開virc.sh parameters are: --hello prints Hello World! --test prints test message. --kbomb runs the kbomb apcs program. --help prints this message. [john@ethernet Desktop]$ sh virc.sh --hello #使用hello選項 Hello World! [john@ethernet Desktop]$ sh virc.sh --kbomb Please input 'N M K':5 2 4 #輸入5 2 4 3 ``` 可以作到這樣呢 ## 先學基礎的變數吧: 1.用echo印出變數: ``` echo ${變數} #example [john@ethernet Desktop]$ echo ${RANDOM} #0到32767的整數 12354 ``` 2.查看系統變數:(都是大寫)env:環境變數,set:環境加自訂變數 ``` [john@ethernet Desktop]$ env XDG_SESSION_DESKTOP=KDE LOGNAME=john XDG_SESSION_TYPE=x11 XAUTHORITY=/home/john/.Xauthority MOTD_SHOWN=pam GTK2_RC_FILES=/etc/gtk-2.0/gtkrc:/home/john/.gtkrc-2.0:/home/john/.config/gtkrc-2.0 HOME=/home/john LANG=zh_TW.UTF-8 XDG_CURRENT_DESKTOP=KDE ...... ``` 3.設定變數基礎: ``` [john@ethernet Desktop]$ virc=cool [john@ethernet Desktop]$ echo ${virc} cool [john@ethernet Desktop]$ 1virc=cool #開頭不能為數字 bash: 1virc=cool:指令找不到 [john@ethernet Desktop]$ virc = cool #等號兩邊不能直接接空白字元 bash: virc:指令找不到 [john@ethernet Desktop]$ export virc #將virc導出為環境變數 ``` 4.設定變數進階: 一,變數中的指令 ``` echo $(指令輸出結果) [john@ethernet Desktop]$ echo $(uname -r) #linux內核版本 5.4.113-1-lts54 #變數=$(指令)的結果 [john@ethernet Desktop]$ myname=$(uname -r) [john@ethernet Desktop]$ echo ${myname} 5.4.113-1-lts54 #當然還可以更活用比如: [john@ethernet Desktop]$ cd /lib/modules/$(uname -r)/kernel #進入到目前內核的模組目錄 [john@ethernet kernel]$ ``` 二,變數中的變數 ``` [john@ethernet Desktop]$ echo ${virc} cool [john@ethernet Desktop]$ virc=${virc}verycool [john@ethernet Desktop]$ echo ${virc} coolverycool ``` 5.萬用字元 \* 代表『 0 個到無窮多個』任意字元 ? 代表『一定有一個』任意字元 [ ] 同樣代表『一定有一個在括號內』的字元(非任意字元)。例如 [abcd] 代表『一定有一個字元,可能是 a, b, c, d 這四個任何一個』 [ - ] 若有減號在中括號內時,代表『在編碼順序內的所有字元』。例如 [0-9] 代表 0 到 9 之間的所有數字,因為數字的語系編碼是連續的! [^ ] 若中括號內的第一個字元為指數符號 (^) ,那表示『反向選擇』,例如 [^abc] 代表 一定有一個字元,只要是非 a, b, c 的其他字元就接受的意思。 6.特殊符號: \\ 跳脫符號:將『特殊字元或萬用字元』還原成一般字元 | 管線 (pipe):分隔兩個管線命令的界定(之後講); ; 連續指令下達分隔符號:連續性命令的界定 (注意!與管線命令並不相同) ~ 使用者的家目錄 7.簡單運算 ``` declare [-aixr] variable 選項與參數: -a :將後面名為 variable 的變數定義成為陣列 (array) 類型 -i :將後面名為 variable 的變數定義成為整數數字 (integer) 類型 -x :用法與 export 一樣,就是將後面的 variable 變成環境變數; -r :將變數設定成為 readonly 類型,該變數不可被更改內容,也不能 unset [john@ethernet Desktop]$ declare -i number=50 [john@ethernet Desktop]$ number=$((${number}+100)) [john@ethernet Desktop]$ echo ${number} 150 ``` \+ - * / % ## 判斷式與迴圈: 8.if判斷式 ``` if [ 條件判斷式一 ]; then 當條件判斷式一成立時,可以進行的指令工作內容; elif [ 條件判斷式二 ]; then 當條件判斷式二成立時,可以進行的指令工作內容; else 當條件判斷式一與二均不成立時,可以進行的指令工作內容; fi ``` 9. case ..... esac 判斷式 ``` case $變數名稱 in <==關鍵字為 case ,還有變數前有錢字號 "第一個變數內容") <==每個變數內容建議用雙引號括起來,關鍵字則為小括號 ) 程式段 ;; <==每個類別結尾使用兩個連續的分號來處理! "第二個變數內容") 程式段 ;; *) <==最後一個變數內容都會用 * 來代表所有其他值 不包含第一個變數內容與第二個變數內容的其他程式執行段 exit 1 ;; esac <==最終的 case 結尾! ``` 10.while do done, until do done 迴圈 ``` while [ condition ] <==中括號內的狀態就是判斷式 do <==do 是迴圈的開始! 程式段落 done <==done 是迴圈的結束 ``` ``` until [ condition ] do 程式段落 done ``` 11.for...do...done 迴圈 ``` for var in con1 con2 con3 ... do 程式段 done #example [john@ethernet Desktop]$ for apcs in c++ python c java do echo "There are ${apcs} in apcs" done There are c++ in apcs There are python in apcs There are c in apcs There are java in apcs #or [john@ethernet Desktop]$ for apcs in c++ python c java; do echo "There are ${apcs} in apcs"; done There are c++ in apcs There are python in apcs There are c in apcs There are java in apcs #or [john@ethernet Desktop]$ declare -i apcs=0 [john@ethernet Desktop]$ for apcs in $(seq 1 100) ; do apcs=$(($apcs+1)) ; done #(seq 1 100為1到100) [john@ethernet Desktop]$ echo ${apcs} 101 ``` 12.for...do...done 迴圈 ``` for (( 初始值; 限制值; 執行步階 )) do 程式段 done #初始值:某個變數在迴圈當中的起始值,直接以類似 i=1 設定好; #限制值:當變數的值在這個限制值的範圍內,就繼續進行迴圈。例如 i<=100; #執行步階:每作一次迴圈時,變數的變化量。例如 i=i+1,i++ #example [john@ethernet Desktop]$ s=0 [john@ethernet Desktop]$ nu=10 [john@ethernet Desktop]$ for (( i=1; i<=${nu}; i=i+1 )) do s=$((${s}+${i})) done [john@ethernet Desktop]$ echo ${s} 55 ``` ## 參考資料與延伸學習 [http://linux.vbird.org/linux_basic/0320bash.php](http://linux.vbird.org/linux_basic/0320bash.php) [http://linux.vbird.org/linux_basic/0340bashshell-scripts.php](http://linux.vbird.org/linux_basic/0340bashshell-scripts.php)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up