http://www.runoob.com/linux/linux-shell.html
https://linuxconfig.org/bash-scripting-tutorial
https://github.com/epety/100-shell-script-examples
變數 型態(轉型)
在Shell Script中,所有的變數都視為字串,因此不需要在定義變數類型。
id=2013001 -> 定義變數時前面不加「$」符號
echo $id -> 使用變數時前面要加「$」符號
注意,在等號的二邊不可以有空白,否則將出現錯誤
$? :表示上一個指令的離開狀況,一般指令正常離開會傳回 0。不正常離開則會傳回 1、2 等數值。
$1 :表示輸入的第一個參數,$2 則為第二個參數,依此類推。
$0 :shell script的檔名。
$@ :即代表 $1, $2,....直到所有參數結束。也就是說 $@ 代表了 "$1" "$2" "$3"....。
$* :所有參數無間隔的連在一起,成為單一個參數。也就是說 $* 代表了 "$1 $2 $3..."
指令的輸出傳回給變數
指令前後加上關鍵字「`」,
now=`date`
echo now
結果會秀出「Mon Dec 16 09:31:44 EAT 2013」
如果是使用單引號,則變數會當成一般文字;雙引號才會解譯成變數
常用關鍵字
#!/bin/sh
printf
read 利用read指令來讀取輸入的資料
echo echo指令內定會自動換行
readonly 唯讀
unset 刪除變數
Example
#!/bin/sh
now=`date`;
echo $now;
printf "請輸入您的名字";
read name;
echo "Your name is $name";
myUrl="http://www.w3cschool.cc"
readonly myUrl
邏輯、數字運算、基本流程語法
- 在 shell 中的四則運算必須使用 expr 這個指令來輔助。注意,在 + - * / 的二邊都有空白,如果沒有空白將產生錯誤
注意的是乘號 * 。因為 * 有其他意義,所以要使用 \* 來代表。另外,也可以用 % 來求餘數
&&與||
a && b如果 a 是真,則執行 b。如果 a 是假,則不執行 b。
a || b如果 a 是假,則執行 b。如果 a 是真,則不執行 b。
常用關鍵字
&&
||
test test 及 [ 來做運算,運算所傳回的結果是真 (true) 或假 ( false)
[] 使用 [ 表達式 ] 來替代 test,要注意的是 [ ] 中的必須有空白間隔
-n str1 :如果字串 str1 的長度大於 0 則傳回 true。
-z str1 :如果字串 str1 的長度等於 0 則傳回 true。
str1 = str2 :如果字串str1等於字串str2則傳回 true,等號二邊有空白。
str1 != str2 :如果 str1 不等於 str2 則傳回 true。!= 的二邊有空白。
a -eq b :Equal,a 等於 b 則傳回真 (true)。
a -ne b :Not equal,a 不等於 b 則傳回真 (true)。
a -gt b :Grwater than,a 大於 b 則傳回真 (true)。
a -lt b :Less Than,a 小於 b 則傳回真 (true)。
a -ge b :Greater or equal,a 大於或等於 b 則傳回真 (true)。
a -le b :Less or equal,a 小於或等於 b 則傳回真 (true)。
流程控制
if elif else
if [ "${yn}" == "Y" ] || [ "${yn}" == "y" ]; then
echo "OK, continue"
elif [ "${yn}" == "N" ] || [ "${yn}" == "n" ]; then
echo "Oh, interrupt!"
else
echo "I don't know what your choice is"
fi
case
case $變數名稱 in <==關鍵字為 case ,還有變數前有錢字號
"第一個變數內容") <==每個變數內容建議用雙引號括起來,關鍵字則為小括號 )
程式段
;; <==每個類別結尾使用兩個連續的分號來處理!
"第二個變數內容")
程式段
;;
*) <==最後一個變數內容都會用 * 來代表所有其他值
不包含第一個變數內容與第二個變數內容的其他程式執行段
exit 1
;;
esac <==最終的 case 結尾!『反過來寫』思考一下!
# read -p "Input your choice: " choice # 暫時取消,可以替換!
# case ${choice} in # 暫時取消,可以替換!
case ${1} in # 現在使用,可以用上面兩行替換!
"one")
echo "Your choice is ONE"
;;
"two")
echo "Your choice is TWO"
;;
"three")
echo "Your choice is THREE"
;;
*)
echo "Usage ${0} {one|two|three}"
;;
esac
while do done
while [ condition ] <==中括號內的狀態就是判斷式
do <==do 是迴圈的開始!
程式段落
done <==done 是迴圈的結束
until do done
until [ condition ]
do
程式段落
done
for
for var in con1 con2 con3 ...
do
程式段
done
###########第二種寫法
for (( 初始值; 限制值; 執行步階 ))
do
程式段
done
for i in $(seq 1 100)
do
echo $i
done
陣列、字典、組數
字串處理
字串長度
string="abcd"
echo ${#string} #输出 4
字串切割
string="runoob is a great site"
echo ${string:1:4} # 输出 unoo
日期處理
函式、方法、介面
function
- 在使用函式之前一定要先定義它,也就是在一個 Shell Script 中,一定要先寫函式的內容, 在函式之後再寫一般的程式部份。
- 在Script中的變數全部都是全域變數 (Global),所以函式中的變數會影響函式之外的其他部份。
- 在命令列中輸入的參數是以 $1,$2來讀取,但是這些參數並沒有辦法在函式中使用。
傳給函式的方法和在命令列中一樣,例如:[函式名稱] arg1 arg2..。 傳進函式的變數一樣會以 $1,$2來儲存並使用。
addnum1 ( )
{
echo 'Function $1 is' $1
echo 'Function $2 is' $2
}
echo 'Command $1 is' $1
echo 'Command $2 is' $2
a=`expr $1 + 10`
b=`expr $2 + 10`
addnum1 $a $b
程式執行:
[root@oel62 test]# ./test01.sh 2 3
結果:
Command $1 is 2
Command $2 is 3
Function $1 is 12
Function $2 is 13
例外
Debug
[dmtsai@study ~]$ sh [-nvx] scripts.sh
選項與參數:
-n :不要執行 script,僅查詢語法的問題;
-v :再執行 sccript 前,先將 scripts 的內容輸出到螢幕上;
-x :將使用到的 script 內容顯示到螢幕上,這是很有用的參數!
範例一:測試 dir_perm.sh 有無語法的問題?
[dmtsai@study ~]$ sh -n dir_perm.sh
# 若語法沒有問題,則不會顯示任何資訊!
範例二:將 show_animal.sh 的執行過程全部列出來~
[dmtsai@study ~]$ sh -x show_animal.sh
+ PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/root/bin
+ export PATH
+ for animal in dog cat elephant
+ echo 'There are dogs.... '
There are dogs....
+ for animal in dog cat elephant
+ echo 'There are cats.... '
There are cats....
+ for animal in dog cat elephant
+ echo 'There are elephants.... '
There are elephants....