這個一個直譯式的程式碼,所以,我們在第一行定義使用的解譯程式是什麼
#!/bin/bash
當程式撰寫完成後,再定義檔案的權限,可以直接執行
chmod 755 a.sh
./a.sh
若在程式內需要輸入的動作採用read 指令
read -p "輸入數字" NUM
echo ${NUM}
輸出字串有2種指令
#這是字串的輸出
echo ${NUM}
#可以透過格式化,指定輸出格式
printf "%d" ${NUM}
變數的定義
Tea="red123456"
變數在給值時與等號之間不能有空白
命名的規格如下:
1. 只能使用 英文、數字(不能為開頭)及 _(下底線)。
2.不能使用bash 裡面的保留字
local A1="test";  # 將定義為函式內使用。不會影響外部的函式值。
local -a 宣告變數為陣列
local -A 宣告變數為 Associative array (key-value)
local -r 代表 readonly
local -n 把另外一個變數內容也指到這個變數
local -p 把變數內容打出來,配合 eval 可以玩很多東西
local -i 把變數當作整數
使用時一般建議使用大括號將變數名稱包起來,防此直譯時出現錯誤
echo ${NUM}
使用 readonly 後,這個變數將不能再被改變
readonly NUM
使用 unset 後,該變數將從當前的運作中被刪除
unset NUM
讀取變數的長度
echo ${#Tea}   # 输出 9
echo ${#Tea[0]}   # 输出 9
取出特定的內容
echo ${Tea:1:4} # 输出 ed12
陣列(bash 只支援一維陣列,其他的sh 不確定)
array_row=(value0 value1 value2 value3)
也可以是
array_row[0]=value0 
array_row[1]=value1
array_row[2]=value2
array_row[3]=value3
將字串轉換成array
str="1 2 3 4 5"
array=(${str})
之後array[0]=1
追加陣列在後面值,由其是不知道最後一個陣列的編號時
array+=('100')
#讀取陣列n的值
valuen=${array_row[n]}
#輸出所有的陣列的值
echo ${array_row[@]}
# 取得陣列的數量
length=${#array_row[@]}
# 或者
length=${#array_row[*]}
# 取得陣列中n的字串長度
lengthn=${#array_row[n]}
簡易的四則運用,運算都會使用expr 或者 awk 及 sed 指令做字串切割。在不使用expr等外部工具的情況下。可以使用下列方式進行
使用$(()) 將要做的計算或判斷放置其中
((a++)) #變數累加
echo $((1+50)) # 簡單運算 51
echo $((2#111)) # 轉進位 把2進位的111轉成10進位
echo $(($a+2 == $b)) #比大小用符號 >, <, ==
$ echo $((a > b ? a : b)) #條件式輸出
浮點數的 Workaround (awk, bc)
浮點運算
$ a=314
$ echo $(awk "BEGIN{print $a / 100 * 2}")
6.28
浮點數比較
pi=3.14
if [ `echo "$pi < 3.15" | bc` -eq 1 ]; then
expr 運算方式
| 運算符 | 說明 | 
| + | 加法 | 
| – | 减法 | 
| * | 乘法(此處在使用時需加上\才能使用) | 
| / | 除法 | 
| % | 取餘數 | 
執行外部程式後取值的方式
# 一般常用這個方式
FileList=`ls /tmp`
# 或者這個方式也可以
FileList=$(ls /tmp)
註解的方式
單行的註解是使用#號為開頭,但#! 開頭,代表的是接列的程式碼,預設使用什麼程式來運行
多行的方式有下列3種方式
方法一
:<<EOF
註解
EOF
方法二
:<<'
註解
'
方法三
:<<!
註解
!
參數的傳遞
在程式的運行時,我們可以透過argv 的方式,帶入更多的參數在script 例如:./a.sh 1 2 3 4 5 6
| 變數 | 說明 | 
| $# | 傳遞參數的數量 | 
| $* | 以一個字串儲存所有輸入的參數 | 
| $$ | 當前的PID值 | 
| $! | 最後一個執行的PID值 | 
| $@ | 和$*類似,但他是以陣列來儲存所有的參數 | 
| $- | 與set 指令相同 | 
| $? | 顯示最後執行的程式退出時的狀態,0代表沒有錯誤 | 
| $n | n為0時,代表程式本身的名稱,1~n 為參數編號,超過10以上需要使用{}包起來,例如:${10} | 
| $_ | 最後一個參數 | 
函式的設計,參數的代入方式和程式的代入是相同的,宣告時不用特別的去說明順序。回傳值為0~255。相同的使用$? 方式查詢,在定義時,前面的function 可寫可不寫。
function EX1(){
    echo $1
    return 255
}
EX1 abc
echo $?
執行結果為
abc
255
IF 判斷常用的幾種用法為,要注意的是if內必須有動作
if [ "${a}" = "abc" ]; then 
    echo "OK"
fi
if [ "${a}" = "abc" ]
then
    echo "OK" 
fi
if [ "${a}" = "abc" ]; then
    echo "OK"
else 
    echo "Fail"
fi
if [ "${a}" = "abc" ]
then
    echo "OK"
else 
    echo "Fail"
fi
if [ "${a}" = "abc" ]
then
    echo "OK"
elif [ "${a}" = "ddd" ]
    echo "ok2"
else 
    echo "Fail"
fi
其他寫法
[ "abc" = "abc" ] && echo "相同" || echo "不相同"
等於
if [ "abc" == "abc" ]
then
    echo "相同"
else 
    echo "不相同"
fi
關係運算符的比較,只支援數值
| 運算符 | 說明 | 
| -eq | 等於 ,若使用(( … )),則可以使用== | 
| -ne | 不等於 | 
| -gt | 大於,若使用(( … )),則可以使用> | 
| -lt | 小於 ,若使用(( … )),則可以使用< | 
| -ge | 大於等於 | 
| -le | 小於等於 | 
布爾/邏輯運算符的比較
| 運算符 | 說明 | 例子 | 
| ! | Not | [ ! false ] 返回 true | 
| -o | Or | [[ 10 -lt 10 -o 10 -gt 100 ]] 返回 true | 
| || | Or | [[ 10 -lt 10 || 10 -gt 100 ]] 返回 true  另一種用途是在簡寫時,用於不成立時使用  | 
| -a | And | [[ 10 -lt 10 -a 100 -gt 100 ]] 返回 true | 
| && | And | [[ 10 -lt 10 && 100 -gt 100 ]] 返回 true  另一種用途是在簡寫時,用於成立時使用  | 
字串運算符的比較
| 運算符 | 說明 | 例子 | 
| = | 相等 | [ “a” = “a” ] | 
| == | 相等 ,判斷式中必須使用[[ ]] 包起來 | [ [ “a” == “a” ] ] | 
| != | 不相等 | [ “a” != “a” ] | 
| =~ | 正規表示法比對字串,判斷式中必須使用[[ ]] 包起來 | [ [ “Hello, world.” =~ “^Hello” ] ] | 
| -z | 檢查字串是否為0 | [ -z $a ] | 
| -n | 檢查字串是否不為0 | [ -n $a ] | 
| $ | 檢查字串是否為空 | [ $a ] | 
文件檢測運算符 使用方式為 [ -b $file ]
| 運算符 | 說明 | 
| -b file | 檢查文件是否為 Block 設備檔案 | 
| -c file | 檢查文件是否為 Char 設備檔案 | 
| -d file | 檢查文件是否為 目錄 | 
| -f file | 檢查文件是否為 一般文件(不是目錄和設備檔案) | 
| -g file | 檢查文件是否為 設定SGID | 
| -k file | 檢查文件是否為 設定 Sticky Bit | 
| -p file | 檢查文件是否為 管道 | 
| -u file | 檢查文件是否為 設定SUID | 
| -r file | 檢查文件是否為 可讀 | 
| -w file | 檢查文件是否為 可寫 | 
| -x file | 檢查文件是否為 可執行 | 
| -s file | 檢查文件是否為 为空(文件大小是否大于0) | 
| -e file | 檢查文件(包含目錄)是否為 存在 | 
| -S file | 檢查文件是否為 socket | 
| -L file | 檢查文件是否為 符號連結 | 
case … esac ,類似switch case
case $KEY in
"1")
    command1
    ;;
"2")
    command2
    ;;
*)
    other
    ;;
esac
回圈的用法
# 這是for 的用法,後面的item1 可以是array
for key in item1 item2 ... itemN
do
     todo
done
for ((初始值;判斷式;步數間隔))
do
    程式碼
done
#這是 while 的範例
while [ "$a" -qt "3" ]
do
    command
done
無限回圈的幾種做法
while :
do
    command
done
while true
do
    command
done
for (( ; ; ))
do
    command
done
# until 為false 時執行,這個部份和 while 不同
until condition
do
    command
done
回圈中常用的指令
| 指令 | 說明 | 
| break | 中斷回圈 | 
| continue | 回到回圈的起啟點再次運行 | 
包含外部程式碼
想要include 外部程式碼做為內部程式呼叫使用
. ./lib.sh
or 
source ./lib.sh
輸入與輸出導向,輸出的資料有3種分類,0 是STDIN,1 是STDOUT,2 是STDERR。例如:1>>/dev/null
| 方法 | 說明 | 例子 | 
| > | 將輸出的內容導向到指定的檔案 | 1>/tmp/a.txt | 
| >> | 將輸出的內容導向並加載到指定的檔案 | 1>>/tmp/a.txt | 
| < | 將檔案的內容,輸入到指定的程式 | wc -l < /tmp/a.txt | 
| << tag | 用於輸入tag 的內容 | wc -l << EOF  aaaaa bbbb ccccc EOF  |