Shell Script
規則
- 指令由上而下、由左而右執行。
- 指令間的多個空白會被忽略掉。
- 如果一行的內容太多,可以使用
\
來延伸至下一行。 - 使用
#
作為註解。
執行
- 絕對路徑:/Users/bobtai/shell.sh
- 相對路徑:./shell.sh
- 以 bash 程式執行:
- 在子程序下執行:sh shell.sh
- 在父程序下執行:source shell.sh
- 差別在於,子程序中的變數在執行完畢後就會消失。
- 其他:放到環境變數 PATH 指定的目錄中。
Script 內容
由上而下依序是:
- 第一行:#!/bin/bash 宣告這個 script 使用 bash 來執行。
#!/bin/bash
- 註解:說明 script 功能、版本、作者、建檔日期。
# Program: # This program do something. # History: # 2017/12/27 Bob First Release.
- 設定 PATH:可讓 script 在執行時,直接下達外部指令,而不必寫絕對路徑。
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH
- 主程式部分
echo "Hello World! \a \n"
- 定義回傳值:
exit n
,當 script 執行完畢,下echo $?
可得到 n 的值。exit 0 # 代表離開 script 時回傳一個 0 給系統
符號
- $?:取得前一個指令的回傳值。
- 若前一個指令的執行結果正確,則會回傳一個 $? = 0 的值。
- 若執行失敗,則會回傳一個非 0 的錯誤碼。
- &&:cmd1 && cmd2
- 若 cmd1 執行完畢且執行結果正確 ($?=0),則執行 cmd2。
- ||:cmd1 || cmd2
- 若 cmd1 執行完畢且執行結果錯誤 ($?≠0),則執行 cmd2。
語法
- $(command):取得指令執行後的結果。
$ echo $(date +%Y_%m_%d) 2017_12_27
$((compute)):取得計算式的結果。
$ echo $((13%3)) 1
test {condition} && {true} || {false}:test 判斷式。
# 判斷 somefile 是否存在?存在顯示 exist,不存在顯示 not exist。 $ test -e somefile && echo "exist" || echo "not exist" # 判斷兩數是否相等? test n1 -eq n2 && echo "equal" || echo "not equal" # 判斷兩字串是否相等? test str1 == str2 && echo "equal" || echo "not equal"
[ ]:判斷符號,與 test 用法類似。
$ [ "str1" == "str2" ] && echo "equal" || echo "not equal" not equal
- 在中括號 [ ] 內的每個元件都需要空白鍵隔開。
- 在中括號 [ ] 內的變數或常數,要以雙引號括號起來。
- 檔名與參數
Test:$ vim file_paras.sh #!/bin/bash echo "The script name is ==> ${0}" echo "Total parameter number is ==> $#" echo "Your whole parameter is ==> $@" echo "The 1st parameter ==> ${1}" echo "The 2nd parameter ==> ${2}"
Definition:$ sh file_paras.sh para1 para2 para3 The script name is ==> file_paras.sh Total parameter number is ==> 3 Your whole parameter is ==> para1 para2 para3 The 1st parameter is ==> para1 The 2nd parameter is ==> para2
- ${0}:檔案名稱
- ${1}, ${2}, ···:參數一、參數二、···
- $#:參數個數
- $@:所有參數值
條件判斷式
- 單層條件判斷式
if [ condition ]; then # if true, do something. fi
- 多條件判斷式:使用
&&
或||
隔開判斷式。if [ "${yn}" == "Y" ] || [ "${yn}" == "y" ]; then echo "OK, continue" exit 0 fi
- 多層條件判斷式
if [ condition1 ]; then # if condition1 true, do something. elif [ condition2 ]; then # if condition2 true, do something. else # if cond1 cond2 false, do something. fi
- 單層條件判斷式
case ... esac 判斷式
case 變數 in "變數值一") # do something ;; "變數值二") # do something ;; *) # 相當於萬用字元,代表任意字元。 # do something ;; esac # 結尾語法為 case 的顛倒
Example:
$ vim hello.sh #!/bin/bash case ${1} in "hello") echo "Hello, how are you?" ;; "") echo "You must input a parameter." ;; *) echo "You input an other parameter." ;; esac
Test:
$ sh hello.sh hello Hello, how are you? $ sh hello.sh You must input a parameter. $ sh hello.sh bob You input an other parameter.
function:因為 shell script 是由上而下執行,function 一定要定義在最上面。
function f_name() { # do something }
Example:
$ vim show123.sh #!/bin/bash function printit(){ echo "Your choice is ${1}." # ${1} 代表這個方法接收一個參數 } case ${1} in "one") printit 1 ;; "two") printit 2 ;; "three") printit 3 ;; *) printit other ;; esac
Test:
$ sh show123.sh one Your choice is 1. $ sh show123.sh bob Your choice is other.
迴圈
while do done:當條件不成立時,才終止迴圈。
while [ condition ] # while與條件之間一定要有空白。 do # do something done
Example:
#!/bin/bash while [ "${yn}" != "yes" ] do read -p "Please input yes to stop:" yn done echo "You input the correct answer."
until do done:當條件成立時,才終止迴圈。
until [ condition ] do # do something done
Example:
#!/bin/bash until [ "${yn}" == "yes" ] do read -p "Please input yes to stop:" yn done echo "You input the correct answer."
以上 while 和 until 的 Example 執行結果相同,差別在於判斷的條件不同。
for do done:限制次數迴圈。
for (( initialization; termination; increment )) do # do something done
Example:
vim count_1_to_100.sh #!/bin/bash s=0 for (( i=1; i<=100; i++ )) do s=$((${s}+${i})) done echo "The result of 1 plus to 100 is ${s}."
Test:
$ sh count_1_to_100.sh The result of 1 plus to 100 is 5050.
參考網站
http://linux.vbird.org/linux_basic/0340bashshell-scripts.php#script