為什么要學習shell編程
1)Linux運維工程師在進行服務器集群管理時,需要編寫shell程序來進行服務器管理。
2)對於javaEE和python程序員來說,工作的需要,你的老大會要求你編寫一些shell腳本進行程序或者是服務器的維護,比如編寫一個定時備份數據庫的腳本。
3)對於大數據程序員來說,需要編寫shell程序來管理集群。
shell是什么
shell是一個命令行解釋器,它為用戶提供了一個向Linux內核發送請求以便運行程序的界面系統級程序,用戶可以用shell來啟動、掛起、停止甚至是編寫一些程序。
shell腳本的執行方式
腳本格式要求:
1)腳本以#!/bin/bash開頭
2)腳本需要有可執行權限
編寫第一個shell腳本
需求說明
創建一個shell腳本,輸出hello world!

腳本的常用執行方式
方式1(輸入腳本的絕對路徑或相對路徑)
1)首先要賦予helloworld.sh腳本的+x權限
2)執行腳本

方式2(sh+腳本)
說明:不用賦予腳本+x權限,直接執行即可。

Shell的變量
介紹:
1)Linux Shell中的變量分為 系統變量和用戶自定義變量。
2)系統變量:$HOME、$PWD、$SHELL、$USER等等
比如:echo $HOME等等。。。

3)顯示當前shell中所有變量:set
shell變量的定義
基本語法:
1)定義變量:變量=值
2)撤銷變量:unset 變量
3)聲明靜態變量:readonly變量,注意:靜態變量不能unset
快速入門
案例1:定義變量A,然后撤銷變量A


案例2:聲明靜態的變量A=99,不能unset


案例3:可把變量提升為全局環境變量,可供其他shell程序使用
shell變量的定義
定義變量的規則
1)變量名稱可以由字母、數字和下划線組成,但是不能以數字開頭。
2)等號兩側不能有空格
3)變量名稱一般習慣為大寫
將命令的返回值賦給變量(重點)
1)A=‘ls -la’反引號,運行里面的命令,並把結果返回給變量A


2)A=$(ls -la)等價於反引號


設置環境變量
基本語法
1)export 變量名=變量值(功能描述:將shell變量輸出為環境變量)
2)source配置文件(功能描述:讓修改后的配置信息立即生效)
3)echo $變量名(功能描述:查詢環境變量的值)
快速入門
1)在/etc/profile文件中定義TOMCAT_HOME 環境變量

2)查看環境變量TOMCAT_HOME的值

3)在另外一個shell程序中使用TOMCAT_HOME


注意:在輸出TOMCAT_HOME環境變量前,需要讓其生效: source /etc/profile
位置參數變量
介紹:
當我們執行一個shell腳本時,如果希望獲取到命令行的參數信息,就可以使用到位置參數變量
比如:./myshell.sh 100 200 ,這個就是一個執行shell的命令行,可以在myshell腳本中獲取到參數信息
基本語法
$n(功能描述:n為數字,$0代表命令本身,$1-$9代表第一到第九個參數,十及以上的參數需要用大括號包含,如${10}
$*(功能描述:這個變量代表命令行所有的參數,$*把所有的參數看成一個整體)
$@(功能描述:這個變量也代表命令行中所有的參數,不過$@把每個參數區分對待)
$#(功能描述:這個變量代表命令行中所有參數的個數)
案例:
編寫一個shell腳本positionPara.sh,在腳本中獲取到命令行的各個參數信息。


預定義變量
基本介紹
就是shell設計者事先已經定義好的變量,可以直接在shell腳本中使用
基本語法
$$ (功能描述:當前進程的進程號(PID))
$! (功能描述:后台運行的最后一個進程的進程號(PID))
$? (功能描述:最后一次執行的命令的返回狀態。如果這個變量的值為0,證明上一個命令正確執行;如果這個變量的值為非0(具體是哪個數,由命令自己來決定),則證明上一個命令執行不正確了。)
應用實例
在一個shell腳本中簡單使用一下預定義變量


運算符
基本介紹
學習如何在shell中進行各種運算操作
基本語法
1)“$((運算式))“或”$[運算式]”


2)expr m+n
注意expr運算符間要有空格
3)expr m-n
4)expr \*,/,% 乘,除,取余


應用案例
案例:請求出命令行的兩個參數[整數]的和


條件判斷
判斷語句
基本語法
[ condition ](注意condition 前后有空格)
#非空返回true,可使用$?驗證(0為true,>=1為false)
應用實例:
[atguigu] 返回true
[] 返回false
[ condition ] && echo OK || echo notok 條件滿足,執行后面的語句
常用判斷條件
1)兩個整數的比較
=字符串比較
-lt小於
-le小於等於
-eq等於
-gt大於
-ge大於等於
-ne不等於
2)按照文件權限進行判斷
-r有讀的權限
-w有寫的權限
-x有執行的權限
3)按照文件類型進行判斷
-f文件存在並且是一個常規的文件
-e文件存在
-d文件存在並是一個目錄
4)應用實例
案例1:“ok”是否等於“ok”
判斷語句:

案例2:23是否大於等於22
判斷語句:

案例3:/root/shell目錄中aaa.txt文件是否存在
判斷語句:

流程控制
if判斷
基本語法:
if [ 條件判斷式 ];then
程序
fi
或者
if [ 條件判斷式 ]
then
程序
elif [ 條件判斷式 ]
then
程序
fi
案例:請編寫一個shell程序,如果輸入的參數大於等於60,則輸出“及格了”,如果小於60,則輸出“不及格”


case語句
基本語法
case $變量名 in
“值1”)
如果變量的值等於值1,則執行程序1
;;
"值2")
如果變量的值等於值2,則執行程序2
;;
...省略其他分支...
*)
如果變量的值都不是以上的值,則執行此程序
;;
esac
應用實例
案例1:當命令行參數是1時,輸出“周一”,是2時,就輸出“周二”,其他情況輸出“other”


for循環
基本語法
for 變量 in 值1 值2 值3...
do
程序
done
應用實例
案例1:打印命令行輸入的參數[這里可以看出$*和$@的區別]




基本語法2
for ((初始值;循環控制條件;變量變化))
do
程序
done
應用實例
案例1:從1加到100的值輸出顯示


while循環
基本語法
while [條件判斷式]
do
程序
done
應用實例
案例1:從命令行輸入一個數n,統計從1+...+n的值是多少?


read讀取控制台輸入
基本語法
read(選項)(參數)
選項:
-p:指定讀取值時的提示符;
-t:指定讀取值時等待的時間(秒),如果沒有在指定的時間內輸入,就不再等待了。
參數:
變量:指定讀取值的變量名
應用實例:
案例1:讀取控制台輸入一個num值
案例2:讀取控制台輸入一個num值,在10秒內輸入。



系統函數
basename基本語法
功能:返回完成路徑最后/的部分,常用於獲取文件名
basename[pathname][suffix]
basename[string][suffix] (功能描述:basename命令會刪掉所有的前綴包括最后一個/字符,然后將字符串顯示出來)
選項:suffix為后綴,如果suffix被制定了,basename會將pathname或string中的suffix去掉。
應用實例
案例1:請返回 /home/aaa/test.txt 的“test.txt”部分

dirname基本語法
功能:返回完成路徑最后/的前面的部分,常用於返回路徑部分
應用實例:
請返回/home/aaa/test.txt 的/home/aaa

自定義函數:
基本語法
[function]funname[()]
{
action;
[return int;]
}
調用的話直接寫函數名:funname [值]
應用實例
案例1:計算輸入兩個參數的和(用read方式輸入)


Shell編程綜合案例
需求分析
1)每天凌晨2:10備份數據庫atguiguDB到 /data/backup/db
2)備份開始和備份結束能夠給出相應的提示信息
3)備份后的文件要求以備份時間為文件名,並打包成.tar.gz的形式,比如:2018-03-12_230201.tar.gz
4)在備份的同時,檢查是否有10天前備份的數據庫文件,如果有就將其刪除。
#!/bin/bash #完成數據庫的定時備份 #備份的路徑 BACKUP=/data/backup/db #當前的時間作為文件名 DATETIME=$(date +%Y_%m_%d_%H%M%S) #可以數據變量調試 #echo $DATETIME echo "============開始備份===========" echo "============備份的路徑是 $BACKUP/$DATETIME.tar.gz=====================" #主機 HOST=localhost #用戶名 DB_USER=root #密碼 DB_PWD=123456789 #備份數據庫名 DATABASE=atguiguDB #創建備份的路徑 #如果備份的路徑存在,就使用,否則就創建 [ ! -d "$BACKUP/$DATETIME" ] && mkdir -p "$BACKUP/$DATETIME"
#mkdir -p :遞歸創建目錄,即使上級目錄不存在,會按目錄層級自動創建目錄
#執行mysql的備份數據庫的指令 mysqldump -u${DB_USER} -p${DB_PWD} --host=$HOST $DATABASE | gzip > $BACKUP/$DATETIME/$DATETIME.sql.gz #打包備份文件 cd $BACKUP tar -zcvf $DATETIME.tar.gz $DATETIME #刪除臨時目錄 rm -rf $BACKUP/$DATETIME #刪除10天前的備份文件 find $BACKUP -mtime +10 -name "*.tar.gz" -exec rm -rf {} \; echo "==============備份文件成功===================="
