Shell Script(Bash)

這個一個直譯式的程式碼,所以,我們在第一行定義使用的解譯程式是什麼

#!/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代表沒有錯誤
$nn為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
-oOr[[ 10 -lt 10 -o 10 -gt 100 ]] 返回 true
|| Or [[ 10 -lt 10 || 10 -gt 100 ]] 返回 true
另一種用途是在簡寫時,用於不成立時使用
-aAnd[[ 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