shell概述linux
1. shell編程的意義git
我的理解,shell編程相似於存儲過程。存儲過程是完成指定功能的一組sql語句集合,而shell編程就是完成指定功能的一組linux命令的集合。例如,咱們要在服務器上部署一個一個項目,一般要作以下幾個操做:sql
每次部署都要執行相同的一套流程,若是能把這些操做放在一個文件裏,只需執行這個文件便可,會明顯提升服務器運維管理的效率。這就是shell編程要知足的需求。docker
2. shell分類shell
linux的shell分類不少,例如編程
其中,最經常使用的是bash shell,即/bin/bash。vim
3. shell編程的格式bash
可使用vi或vim編輯器建立shell腳本文件,其擴展名並無要求,可使用(.sh)表示它是一個shell文件,例如hello.sh、deploy.sh等,可是使用別的擴展名或者不用擴展名也不影響其執行。shell文件的第一行通常要指定shell種類,#!用來告訴系統,這個文件使用哪一個解釋器。例如最經常使用的bash shell這樣寫:服務器
#!/bin/bash #這是單行註釋 echo "hello world" :<<! 這是多行註釋 這是多行註釋 這是多行註釋 ! echo "byebye"
4. shell腳本的執行方式運維
若是給shell腳本賦予了可執行權限,則直接寫文件的路徑名便可執行,可使用絕對路徑或相對路徑,注意若是shell文件正好在當前目錄下,相對路徑要以 ./ 開頭,而不能直接寫文件名。若是並無給shell腳本賦予可執行權限,則須要在文件路徑名前加 sh。通常推薦第一種,即賦予用戶對文件的可執行權限。例如,在當前路徑(/home/dubhlinn)下有一個hello.sh的腳本,
(1) 當用戶對其有可執行權限時:
./hello.sh
/home/dubhlinn/hello.sh
(2) 當用戶對其無可執行權限時:
sh ./hello.sh
sh /home/dubhlinn/hello.sh
shell編程的變量
1. 變量的定義
變量名 = 變量值
#輸出環境變量
echo $HOME echo $USER #自定義變量
A=12 B=hello echo A=$A echo B=$B
shell編程中變量分爲兩類:環境變量、自定義變量。環境變量是linux系統已經預先定義好的變量,能夠直接使用;自定義變量必須先定義,再使用。定義變量的的語法很簡單,可是有幾點須要注意:
2. 聲明環境變量
(1) export 變量名=變量值
(2) source 文件路徑名
第一步跟自定義變量相比,只是多了一個export關鍵字,第二步是爲了讓shell文件生效。完成這兩步以後,能夠在其它的shelle文件或中獲取剛剛聲明的環境變量。而相比之下,自定義變量僅限於在一個shell文件中使用,在其餘的shell文件中沒法使用。
#設置環境變量
export VILLA=Spain7 export TORRES=Spain9
須要注意的是,在一個shell文件中,自定義變量會覆蓋同名的環境變量,例如
#輸出環境變量
echo VILLA=$VILLA #自定義變量
VILLA=Bacelona7 #輸出,看是環境變量仍是自定義變量
echo VILLA=$VILLA
第一次輸出的是環境變量的值:Spain7,第二次輸出的是自定義變量的值:Bacelona7。
3. 變量的撤銷
unset 變量名
#撤銷變量
B=hello unset B echo B=$B
4. 靜態變量,不能被撤銷
readonly 變量名=變量值
:<<! 靜態變量 不能撤銷 ! readonly C=5 echo C=$C unset C echo C=$C
執行這個腳本會報錯,由於C是靜態變量,不能使用unset將其撤銷。
5. 將linux命令的執行結果賦給變量
變量名=`命令` 或 變量名=$(命令)
#將linux命令的執行結果賦給變量,兩種方式等價
A=`ls -lh` B=$(date) echo A=$A echo B=$B
6. 接收參數
在shell腳本中能夠像Java方法同樣接收形參,其語法格式以下
#輸出單個參數
echo 第1個參數爲$1 echo 第2個參數爲$2 echo 第10個參數爲${10} #輸出所有參數,且做爲一個總體
echo 所有參數爲$*
#輸出所有參數,且分別對待
echo 參數分別爲$@ #輸出參數個數
echo 總共有$#個參數
在執行這個shell腳本時,能夠傳入參數,例如 ./hello.sh 1 2 3
shell編程的運算符
shell的運算符自己跟Java、JavaScript等語言基本同樣:+、-、*、/、%等,但實際應用有一些獨特的規則,主要有如下三種使用方法
其中,前兩種方式的運算符之間不能加空格,第三種方式的運算符之間必須加空格,並且括號、乘號須要加轉義符號,即 \(、\)、\* 。這些規則看起來有點奇怪,下面用幾個具體的示例來講明。
1. 求 (3+5)*4/(2+1)的值
#使用第一種方式計算
R1=$(((3+5)*4/(9-1))) echo R1=$R1 #使用第二種方式計算
R2=$[(3+5)*4/(9-1)] echo R2=$R2 #使用第三種方式計算
R3=`expr \( 3 + 5 \) \* 4 / \( 9 - 1 \)` echo R3=$R3
2. 求第一個參數和第二個參數的和,而後取除以第三個參數的餘數
#使用第一種方法計算
R1=$((($1+$2)%$3)) echo R1=$R1 #使用第二種方法計算
R2=$[($1+$2)%$3] echo R2=$R2 #使用第三種方法計算
R3=`expr \( $1 + $2 \) % $3` echo R3=$R3
shell編程的條件分支語句
1. if條件分支語句
if [ 條件1 ]
then
語句1
elif [ 條件2 ]
then
語句2
else
語句3
fi
其中,中括號與條件之間必須加空格。
符號 | 意義 |
= | 兩個字符串是否相等 |
-lt | 小於 |
-le | 小於等於 |
-eq | 等於 |
-ge | 大於等於 |
-gt | 大於 |
-ne | 不等於 |
-r | 文件或目錄有讀的權限 |
-w | 文件或目錄有寫的權限 |
-x | 文件或目錄有執行權限 |
-f | 文件存在而且是一個常規文件 |
-e | 文件存在 |
-d | 文件存在而且是一個目錄 |
2. case條件分支語句
case 變量 in
值1)
語句1
;;
值2)
語句2
;;
*)
語句3
;;
esac
3. 應用示例
#判斷文件是否存在
if [ -e /home/dubhlinn/shell/aaa.txt ] then echo 存在 else echo 不存在 fi #判斷是否是一個目錄
if [ -d /home/dubhlinn/shell ] then echo 是一個目錄 else echo 不是一個目錄 fi #判斷文件是否有可執行權限
if [ -x /home/dubhlinn/shell/hello.sh ] then echo 有可執行權限 else echo 無可執行權限 fi #判斷兩個數字的大小
if [ $[5*3] -ge $[6+7] ] then echo 前者大於等於後者 else echo 前者小於後者 fi #判斷傳入的參數範圍
if [ $1 -gt 90 ] then echo 優秀 elif [ $1 -ge 60 ] then echo 及格 else echo 不及格 fi
#!/bin/bash
:<<! 若是參數是6,則輸出"星期六", 若是參數是7,則輸出"星期日" 若是是其餘,則輸出"工做日" 用兩種判斷語句實現 !
#使用if語句實現
if [ $1 -eq 6 ] then echo 星期六 elif [ $1 -eq 7 ] then echo 星期日 else echo 工做日 fi #使用case語句實現
case $1 in
6) echo 星期六 ;; 7) echo 星期日 ;; *) echo 工做日 ;; esac
shell編程的循環語句
1. for循環
for ((初始值;循環條件;變量變化))
do
表達式
done
2. while循環
while [ 條件 ]
do
表達式
變量變化
done
注意,中括號跟條件之間須要加空格。
3. 使用示例
#!/bin/bash
:<<! 分別使用for循環和while循環 計算從1到控制檯參數的累加之和 例如,控制檯輸入100,則計算從1-100之和 ! #使用for循環
SUM1=0 for ((i=0;i<=$1;i++)) do SUM1=$[$SUM1+$i] done echo SUM1=$SUM1 #使用while循環
SUM2=0 j=1
while [ $j -le $2 ] do SUM2=$[$SUM2+j] j=$[$j+1] done echo SUM2=$SUM2
控制檯交互
1. read關鍵字
read [-p 提示信息] [-t 等待時間] 參數
其中,-p後面接提示信息,顯示在控制檯;-t後面接等待時間(單位是秒),超過這個時間沒有響應則自動退出;參數是用來接收用戶在控制檯輸入的值的變量名。
2. 使用示例
#/bin/bash
#提示用戶輸入一個數字,而後打印到控制檯
read -p "請輸入一個數字" A echo 您輸入的數字是: $A #提示用戶輸入一個數字,而後打印到控制檯,最多等待5秒
read -p "請在5秒鐘以內輸入一個不等於零的數" -t 5 B if [ $B -ne 0 ] then echo 您輸入的數字是:$B else echo 輸入無效 fi
shell函數
shell編程跟其餘編程語言同樣,也有函數(Java中叫方法)。shell函數分爲系統函數和自定義函數,跟變量同樣,系統函數是linux系統已經定義好的,咱們能夠直接拿來用;自定義函數須要本身先定義,再調用。
1. basename函數
basename 全路徑 [後綴]
basename是一個系統函數,用於返回文件名,即最後一個/後面的部分,若是加了中括號內的後綴,表示連後綴也去掉。例如
#!/bin/bash
#返回一個全路徑的文件名
basename /home/dubhlinn/shell/aaa.sh #返回一個全路徑的文件名,去掉後綴
basename /home/dubhlinn/shell/aaa.sh .sh
2. dirname函數
dirname 全路徑
dirname也是一個系統函數,它與basename正好相反,返回的是目錄名,即最後一個/以前的部分。
#!/bin/bash
#返回一個全路徑的目錄名
dirname /home/dubhlinn/shell/aaa.sh
3. 自定義函數的定義格式
function 函數名() {
語句;
[return 返回值;]
}
4. 自定義函數的調用格式
函數名 參數
5. 自定義函數使用示例
#!/bin/bash
:<<! 定義一個函數,求兩個參數之和 ! #定義函數
function getSum() { SUM=$[$A+$B] echo 函數調用結構爲$SUM } #調用函數
A=5 B=6 getSum $A $B