大資料----【Shell程式設計】
Shell程式設計
Shell 是一個用 C 語言編寫的程式,通過 Shell 使用者可以訪問作業系統核心服務。它類似於 DOS 下的 command 和後來的 cmd.exe。Shell 既是一種命令語言,又是一種程式設計語言。Shell script 是一種為 shell 編寫的指令碼程式。Shell 程式設計一般指 shell指令碼程式設計,不是指開發 shell 自身。Shell 程式設計跟 java、php 程式設計一樣,只要有一個能編寫程式碼的文字編輯器和一個能解釋執行的指令碼直譯器就可以了Linux 的 Shell 種類眾多,一個系統可以存在多個 shell,可以通過 cat /etc/shells
Bash
由於易用和免費,在日常工作中被廣泛使用。同時,Bash 也是大多數Linux 系統預設的 Shell。
1. 基本格式
#!/bin/bash
echo "Hello World !"
#!
是一個約定的標記,它告訴系統這個指令碼需要什麼直譯器來執行,即使用哪一種 Shell。
echo
命令用於向視窗輸出文字。
Shell 指令碼的執行:
chmod +x ./hello.sh
#使指令碼具有執行許可權
./hello.sh
#執行指令碼
直接寫 hello.sh,linux 系統會去 PATH 裡尋找有沒有叫 hello.sh的。用 ./hello.sh 告訴系統說,就在當前目錄找。還可以作為直譯器引數執行。直接執行直譯器,其引數就是 shell 腳
本的檔名,如:
絕對路徑讀取
/bin/sh /root/hello.sh
相對路徑讀取
./hello.sh
sh呼叫讀取
sh hello.sh
這種方式執行指令碼,不需要在第一行指定直譯器資訊,寫了也不生效。
shell開發流程:
- 檔名字尾名一般使用
.sh
- 指定本指令碼的解析器是什麼 #!/bin/xxx
- shell指令碼內容
- 給shell指令碼授予執行的許可權(x)
- u(前三位) user g(中間三位) group o(最後三位) other a all
- e.g. o+r g-w 777
- shell執行的三種方式
- 決定路徑 執行指令碼
- ./指令碼
- sh 指令碼
2. Shell 變數
2.1 語法 語法 格式
變數=值
,如:your_name=“itcast.cn”
注意:變數名和等號之間不能有空格
,同時,變數名的命名須遵循如下規則:
- 首個字元必須為字母(a-z,A-Z)
- 中間不能有空格,可以使用下劃線(_)
- 不能使用標點符號
- 不能使用 bash 裡的關鍵字(可用 help 命令檢視保留關鍵字)
2.2 變數 變數 使用
使用一個定義過的變數,只要在變數名前面加$
即可。
your_name=“itcast.cn”
echo $your_name
echo ${your_name}
花括號是可選的,加不加都行,加花括號是為了幫助直譯器識別變數的邊界。已定義的變數,可以被重新定義。使用 readonly 命令可以將變數定義為只讀變數,只讀變數的值不能被改變。使用 unset 命令可以刪除變數。不能刪除只讀變數。
readonly variable_name
unset variable_name
2.3 變數型別
區域性變數 區域性變數在指令碼或命令中定義,僅在當前 shell 例項中有效,其他 shell 啟動的程式不能訪問區域性變數。
環境變數
所有的程式,包括 shell 啟動的程式,都能訪問環境變數,有些程式需要環境變數來保證其正常執行。可以用過 set 命令檢視當前環境變數。
shell 變數
是由 shell 程式設定的特殊變數。shell 變數中有一部分是環境變數,有一部分是區域性變數,這些變數保證了 shell 的正常執行。
3. Shell 引數傳遞
在執行 Shell 指令碼時,可以向指令碼傳遞引數。指令碼內獲取引數的格式為:$n。n 代表一個數字,1 為執行指令碼的第一個引數,2 為執行指令碼的第二個引數,以此類推…… $0 表示當前指令碼名稱。
3.1 特殊字元
命令 | 說明 |
---|---|
$# | 傳遞到指令碼的引數個數 |
$* | 以一個單字串顯示所有向指令碼傳遞的引數 |
$$ | 指令碼執行的當前程序 ID 號 |
$! | 後臺執行的最後一個程序的 ID 號 |
[email protected] | 與$*相同 , 但是使用時加引號,並在引號中返回每個引數。 |
$? | 顯示最後命令的退出狀態。0 表示沒有錯誤,其他任何值表明有錯誤。 |
例子:
#!/bin/bash
echo "第一個引數為:$1";
echo "第二個引數為:$2";
echo "當前指令碼名稱:$0";
echo "引數個數為:$#";
echo "傳遞的引數作為一個字串顯示:$*";
執行指令碼:./test.sh 1 2 3輸出結果為
第一個引數為:1
第二個 引數為:2
當前指令碼名稱:test.sh
引數個數為:3
傳遞的引數作為一個字串顯示:1 2 3
3.2 @ 區別
相同點:都表示傳遞給指令碼的所有引數。
不同點:
不被" "
包含時,$*
和[email protected]
都以**$1 $2… *"會將所有的引數作為一個整體,以**"$1 $2 … $n"**的形式組成一個整串;
"[email protected]"` 會將各個引數分開,以**"$1"** “n” 的形式組成一個引數列表。
4. Shell 運算子
Shell 和其他程式設計語音一樣,支援包括:算術、關係、布林、字串等運算子。原生 bash 不支援簡單的數學運算,但是可以通過其他命令來實現,例如expr。expr 是一款表示式計算工具,使用它能完成表示式的求值操作。
例如,兩個數相加:
val=expr 2 + 2
echo $val ===> 4
注意: 表示式和運算子之間要有空格,例如 2+2 是不對的,必須寫成 2 + 2。 完整的表示式要被 ````包含,注意不是單引號,在 Esc 鍵下邊。
此外,還可以通過(())
、$[]
進行算術運算
count=1
((count++))
echo $count # 2
a=$((1+2)) # 3
a=$[1+2] # 3
5. 流程控制
5.1 if else
語法 : 最後需要反寫if==>fi
if 條件1
then
條件1成立執行的命令
elif 條件2
then
條件2成立執行的命令
else
上述條件都不成立執行的命令N
fi
5.2 for
方式一
在vi編輯器中編寫的(即.sh檔案中編寫)
for N in 1 2 3
do
echo $N
done
或
在控制檯中編寫
for N in 1 2 3; do echo $N; done
或
省略寫法
for N in {1..3}; do echo $N; done
方式二
for ((i = 0; i <= 5; i++))
do
echo "welcome $i times"
done
或
for ((i = 0; i <= 5; i++)); do echo "welcome $i times"; done
5.3 while
方式一
while 表示式或者條件
do
成立執行的命令
…
done
方式二
i=1
while ((i<=3))
do
echo $i
let i++
done
let 命令是 BASH 中用於計算的工具,用於執行一個或多個表示式,變數計算中不需要加上 $ 來表示變數
。自加操作: let no++
自減操作: let no --
方式三:無限迴圈
while true
do
條件成立執行的命令
done
5.4 case
case 值 in
模式 1)
模式1下的命令1
模式1下的命令2
...
模式1下的命令N
;;
模式 2)
模式2下的命令1
模式2下的命令2
...
模式2下的命令N
;;
esac
tips: 最後需要將case反寫 ===> esac , 同時兩個條件用兩個分號分隔
;;
例子
--------------------------------------------------------
算術運算子
#!/bin/bash
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
val=`expr $a - $b`
echo "a - b : $val"
val=`expr $a \* $b`
echo "a * b : $val"
val=`expr $b / $a`
echo "b / a : $val"
val=`expr $b % $a`
echo "b % a : $val"
if [ $a == $b ]
then
echo "a 等於 b"
fi
if [ $a != $b ]
then
echo "a 不等於 b"
fi
執行指令碼,輸出結果如下所示
a + b : 30
a - b : -10
a * b : 200
b / a : 2
b % a : 0
a 不等於 b
乘號(*)前邊必須加反斜槓(\)才能實現乘法運算;
--------------------------------------------------------
關係運算符
關係運算符只支援數字,不支援字串,除非字串的值是數字。
EQ 就是 EQUAL等於
NQ 就是 NOT EQUAL不等於
GT 就是 GREATER THAN大於
LT 就是 LESS THAN小於
GE 就是 GREATER THAN OR EQUAL 大於等於
LE 就是 LESS THAN OR EQUAL 小於等
#!/bin/bash
a=10
b=20
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等於 b"
else
echo "$a -eq $b: a 不等於 b"
fi
if [ $a -ne $b ]
then
echo "$a -ne $b: a 不等於 b"
else
echo "$a -ne $b : a 等於 b"
fi
if [ $a -gt $b ]
then
echo "$a -gt $b: a 大於 b"
else
echo "$a -gt $b: a 不大於 b"
fi
if [ $a -lt $b ]
then
echo "$a -lt $b: a 小於 b"
else
echo "$a -lt $b: a 不小於 b"
fi
if [ $a -ge $b ]
then
echo "$a -ge $b: a 大於或等於 b"
else
echo "$a -ge $b: a 小於 b"
fi
if [ $a -le $b ]
then
echo "$a -le $b: a 小於或等於 b"
else
echo "$a -le $b: a 大於 b"
fi
-----------------------------------------------------------------
布林運算子
#!/bin/bash
a=10
b=20
if [ $a != $b ]
then
echo "$a != $b : a 不等於 b"
else
echo "$a != $b: a 等於 b"
fi
if [ $a -lt 100 -a $b -gt 15 ]
then
echo "$a 小於 100 且 $b 大於 15 : 返回 true"
else
echo "$a 小於 100 且 $b 大於 15 : 返回 false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then
echo "$a 小於 100 或 $b 大於 100 : 返回 true"
else
echo "$a 小於 100 或 $b 大於 100 : 返回 false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then
echo "$a 小於 5 或 $b 大於 100 : 返回 true"
else
echo "$a 小於 5 或 $b 大於 100 : 返回 false"
fi
-------------------------------------------------------------
邏輯運算子
#!/bin/bash
a=10
b=20
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
if [[ $a -lt 100 || $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
----------------------------------------------------------------
字串運算子
下表列出了常用的字串運算子,假定變數 a 為 "abc",變數 b 為 "efg":
#!/bin/bash
a="abc"
b="efg"
if [ $a = $b ]
then
echo "$a = $b : a 等於 b"
else
echo "$a = $b: a 不等於 b"
fi
if [ $a != $b ]
then
echo "$a != $b : a 不等於 b"
else
echo "$a != $b: a 等於 b"
fi
if [ -z $a ]
then
echo "-z $a : 字串長度為 0"
else
echo "-z $a : 字串長度不為 0"
fi
if [ -n $a ]
then
echo "-n $a : 字串長度不為 0"
else
echo "-n $a : 字串長度為 0"
fi
if [ $a ]
then
echo "$a : 字串不為空"
else
echo "$a : 字串為空"
fi
--------------------------------------
檔案測試運算子
檔案測試運算子用於檢測 Unix 檔案的各種屬性。
屬性檢測描述如下:
#!/bin/bash
file="/var/www/itcast/test.sh"
if [ -r $file ]
then
echo "檔案可讀"
else
echo "檔案不可讀"
fi
if [ -w $file ]
then
echo "檔案可寫"
else
echo "檔案不可寫"
fi
if [ -x $file ]
then
echo "檔案可執行"
else
echo "檔案不可執行"
fi
if [ -f $file ]
then
echo "檔案為普通檔案"
else
echo "檔案為特殊檔案"
fi
if [ -d $file ]
then
echo "檔案是個目錄"
else
echo "檔案不是個目錄"
fi
if [ -s $file ]
then
echo "檔案不為空"
else
echo "檔案為空"
fi
if [ -e $file ]
then
echo "檔案存在"
else
echo "檔案不存在"
fi
-----------------------------------------------------------
流程控制語句
-----------------------------------------------------------
if else
if:
if 條件
then
條件成立執行的命令1
條件成立執行的命令2
...
條件成立執行的命令N
fi
寫成一行:if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
if else:
if 條件
then
條件成立執行的命令1
條件成立執行的命令2
...
條件成立執行的命令N
else
條件不成立執行的命令
fi
if else-if else:
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
例子:
a=10
b=20
if [ $a == $b ]
then
echo "a 等於 b"
elif [ $a -gt $b ]
then
echo "a 大於 b"
elif [ $a -lt $b ]
then
echo "a 小於 b"
else
echo "沒有符合的條件"
fi
---------------------------------------------------
case語句
echo '輸入 1 到 4 之間的數字:'
echo '你輸入的數字為:'
read aNum
case $aNum in
1) echo '你選擇了 1'
;;
2) echo '你選擇了 2'
;;
3) echo '你選擇了 3'
;;
4) echo '你選擇了 4'
;;
*) echo '你沒有輸入 1 到 4 之間的數字'
;;
esac
6. 函式使用
所有函式
在使用前必須定義
。這意味著必須將函式放在指令碼開始部分,直至shell 直譯器首次發現它時,才可以使用。呼叫函式僅使用其函式名即可
。
格式:
[ function ] 函式名 [()] // []表示可選
{
操作;
[return int;]//返回
}
1、可以帶 function fun()定義,也可以直接 fun() 定義,不帶任何引數。 2、引數返回,可以顯示加 return ,如果不加,將以最後一條命令執行結果,作為返回值。 return 後跟數值 n(0-255)。
6.1 函式引數
在函式體內部,通過 $n
的形式來獲取引數的值,例如,$1 表示第一個引數,$2 表示第二個引數…
注意,當 n>=10 時,需要使用${n}來獲取引數。
函式例子
#!/bin/bash
demoFun(){
echo "這是我的第一個 shell 函式!"
}
echo "-----函式開始執行-----"
demoFun
echo "-----函式執行完畢-----"
#!/bin/bash
funWithReturn(){
echo "這個函式會對輸入的兩個數字進行相加運算..."
echo "輸入第一個數字: "
read aNum
echo "輸入第二個數字: "
read anotherNum
echo "兩個數字分別為 $aNum 和 $anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
echo "輸入的兩個數字之和為 $? !"
函式返回值在呼叫該函式後通過 $? 來獲得。
#!/bin/bash
funWithParam(){
echo "第一個引數為 $1 !"
a=$1
echo "第二個引數為 $2 !"
echo "第十個引數為 $10 !"
echo "第十個引數為 ${10} !"
echo "第十一個引數為 ${11} !"
echo "引數總數有 $# 個!"
echo "作為一個字串輸出所有引數 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
輸出結果:
第一個引數為 1 !
第二個引數為 2 !
第十個引數為 34 !
第十一個引數為 73 !
引數總數有 11 個!
作為一個字串輸出所有引數 1 2 3 4 5 6 7 8 9 34 73 !