31 shell(1)
20.1 Shell指令碼介紹
1. shell是一種指令碼語言 aming_linux blog.lishiming.net
2. 可以使用邏輯判斷、迴圈等語法
3. 可以自定義函式
4. shell是系統命令的集合
5. shell指令碼可以實現自動化運維,能大大增加我們的運維效率
20.2 Shell指令碼結構和執行
1. 開頭(首行)需要加 : #!/bin/bash
2. 以#開頭的行作為解釋說明 :
3. 指令碼的名字以.sh結尾,用於區分這是一個shell指令碼
4. 執行.sh指令碼方法有兩種 :
1) 先給.sh指令碼新增x許可權:[[email protected] ~]# chmod +x 1.sh
.sh指令碼的絕對路徑回車:[[email protected] ~]# /root/1.sh
2) bash(bash=sh)執行.sh指令碼 :[[email protected] ~]# bash 1.sh
5. 檢視指令碼執行過程 :[[email protected]
6. 檢測指令碼是否有語法錯誤 ?[[email protected] ~]# sh -n 1.sh
20.3 date命令用法
1. 檢視當前時間 :[[email protected] ~]# date
2.年:[[email protected] ~]#date +%Y 或 [[email protected] ~]#date +%y
月:[[email protected]
分鐘:[[email protected] ~]#date +%M
日期:[[email protected] ~]# date +%d
月日年:[[email protected] ~]# date +%D
年月日:[[email protected] ~]# date +%Y%m%d
年-月-日:[[email protected] ~]# date +%F
小時:[[email protected] ~]# date +%H
秒:[[email protected] ~]# date +%S
時間戳(距離1970年1月1日零點零分到現在有多少秒):[[email protected] ~]# date +%s
時:分鐘:秒:[[email protected] ~]# date +%H:%M:%S 或 [[email protected] ~]# date +%T
周(星期幾):[[email protected] ~]# date +%w
今年第幾周(第幾個星期):[[email protected] ~]# date +%W
顯示日曆:[[email protected] ~]# cal
前一天(昨天):[[email protected] ~]# date -d "-1 day" +%F
上個月:[[email protected] ~]# date -d "-1 month" +%F
前一年(去年):[[email protected] ~]# date -d "-1 years" +%F
前一小時:[[email protected] ~]# date -d "-1 hour" +%F
前一分鐘:[[email protected] ~]# date -d "-1 min" +%F
時間戳(當前時間到1970年1月1日零點零分有多少秒):[[email protected] ~]# date +%s
通過時間戳,翻譯成日期時間:[[email protected] ~]# date -d @1505206911
通過日期時間,轉換成時間戳:[[email protected] ~]# date +%s -d "2017-09-12 17:01:51"
20.4 Shell指令碼中的變數
1. 當指令碼中使用某個字串較頻繁並且字串長度很長時就應該使用變數代替
2. 使用條件語句時,常使用變數 if [ $a -gt 1 ]; then ... ; fi
3. 引用某個命令的結果時,用變數替代 n=`wc -l 1.txt`
4. 寫和使用者互動的指令碼時,變數也是必不可少的 read -p "Input a number: " n; echo $n 如果沒寫這個n,可以直接使用$REPLY
5. 內建變數 $0, $1, $2… $0表示指令碼本身,$1 第一個引數,$2 第二個 .... $#表示引數個數
6. 數學運算a=1;b=2; c=$(($a+$b))或者$[$a+$b]
20.5 Shell指令碼中的邏輯判斷
格式1:if 條件 ; then 語句; fi
1. 建立if1.sh測試指令碼:[[email protected] ~]# vi if1.sh
a=5,如果a大於3,滿足這個條件,顯示ok , 新增內容:
#!/bin/bash
a=5
if [ $a -gt 3 ]
then
echo ok
fi
2. 執行if1.sh指令碼:[[email protected] ~]# sh if1.sh
格式2:if 條件; then 語句; else 語句; fi
1. 建立if2.sh測試指令碼:[[email protected] ~]# vi if2.sh
a=1,如果a大於3,滿足這個條件,顯示ok; 不滿足這個條件,顯示nook
新增內容:
#!/bin/bash
a=1
if [ $a -gt 3 ]
then
echo ok
else
echo noook
fi
2. 執行if2.sh指令碼:[[email protected] ~]# sh if2.sh
檢視執行過程:[[email protected] ~]# sh -x if2.sh
格式3:if …; then … ;elif …; then …; else …; fi
1. 建立if3.sh測試指令碼:
a=3,如果a大於4,(不滿足繼續判斷)a大於6; 滿足小於6並且大於1,顯示nook , 新增內容:
#!/bin/bash
a=3
if [ $a -gt 4 ]
then
echo ">"
elif [ $a -gt 6 ]
then
echo "<6 && >1"
else
echo nook
fi
2. 執行if3.sh指令碼:[[email protected] ~]# sh if3.sh
檢視執行過程:[[email protected] ~]# sh -x if3.sh
邏輯判斷表示式:
-gt(>) -lt(<) -eq(==) -ne(!=) -ge(>=) -le(<=)
-gt大於 -lt小於 -eq等於 -ne不等於 -ge大於等於 -le小於等於
例:if [ $a -gt $b ] if [ $a -lt 5 ] if [ $b -eq 10 ] # 可以使用 &&並且 ||或者 多個判斷條件
例: if [ $a -gt 5 ] && [ $a -lt 10 ]; then
if [ $b -gt 5 ] || [ $b -lt 3 ]; then
20.6 檔案目錄屬性判斷
[ -f file ]判斷是否是普通檔案,且存在
1. 建立file1.sh測試指令碼:[[email protected] ~]# vi file1.sh
判斷/tmp/hao.txt是不是普通檔案?是否存在?如果不存在,建立這個檔案!新增內容:
#!/bin/bash
f="/tmp/hao.txt"
if [ -f $f ]
then
echo $f exist
else
touch $f # 建立
fi
2. 執行file1.sh指令碼(檔案不存在的情況下):[[email protected] ~]# sh -x file1.sh
執行filel.sh指令碼(檔案存在的情況下):[[email protected] ~]# sh -x file1.sh
[ -d file ] 判斷是否是目錄,且存在
1. 建立file2.sh測試指令碼:[[email protected] ~]# vi file2.sh
判斷/tmp/hao.txt是不是目錄?是否存在?如果不是目錄,也不存在這樣的目錄,建立這個目錄! 新增內容:
#!/bin/bash
f="/tmp/hao.txt"
if [ -d $f ]
then
echo $f exist
else
touch $f
fi
2. 執行file2.sh指令碼(檔案不存在的情況下):[[email protected] ~]# sh -x file2.sh
[ -e file ] 判斷檔案或目錄是否存在
1. 建立file3.sh測試指令碼:[[email protected] ~]# vi file3.sh
判斷/tmp/hao.txt不管是目錄或檔案,只要不存在的,就建立檔案或目錄!新增內容:
#!/bin/bash
f="/tmp/hao.txt"
if [ -e $f ]
then
echo $f exist
else
touch $f
fi
2. 執行file3.sh指令碼[[email protected] ~]# sh -x file3.sh
[ -r file ] 判斷檔案是否可讀
1. 建立file4.sh測試指令碼:判斷/tmp/hao.txt檔案是否可讀?
[[email protected] ~]# vim file4.sh # 新增內容:
#!/bin/bash
f="/tmp/hao.txt"
if [ -r $f ]
then
echo $f readable
fi
2. 執行file4.sh指令碼 : [[email protected] ~]# sh -x file4.sh
[ -w file ] 判斷檔案是否可寫
1. 建立file5.sh測試指令碼:判斷/tmp/hao.txt檔案是否可寫?
[[email protected] ~]# vim file5.sh # 新增內容:
#!/bin/bash
f="/tmp/hao.txt"
if [ -w $f ]
then
echo $f writeable
fi
2. 執行file5.sh指令碼
[[email protected] ~]# sh -x file5.sh #
[ -x file ] 判斷檔案是否可執行
1. 建立file5.sh測試指令碼:判斷/tmp/hao.txt檔案是否可執行?
[[email protected] ~]# vim file6.sh # 新增內容:
#!/bin/bash
f="/tmp/hao.txt"
if [ -x $f ]
then
echo $f exeable
fi
2. 執行file56.sh指令碼(沒有輸出就是不可執行!可是指令碼配置也是許可權) [[email protected] ~]# sh -x file6.sh
20.7 if特殊用法
if [ -z "$a" ] 這個表示當變數a的值為空時會怎麼樣
if [ -n "$a" ] 表示當變數a的值不為空
if grep -q '123' 1.txt; then 表示如果1.txt中含有'123'的行時會怎麼樣
if [ ! -e file ]; then 表示檔案不存在時會怎麼樣 取反
if (($a<1)); then …等同於 if [ $a -lt 1 ]; then…
[ ] 中不能使用<,>,==,!=,>=,<=這樣的符號
grep結合if示例:
-q 引數,本意是 Quiet:不列印 -w精準匹配 # 如果root存在就輸入存在
20.8 cace判斷(上) 20.9 cace判斷(下)
格式:在case程式中,可以再條件中使用 | ,表示或的意思
case 變數名 in
value1) ---第一個判斷
command
;;
value2) ---第二個判斷
command
;;
*) --除此之外
command
;;
esac
#!/bin/bash
read -p "Please input a number: " n ---讓使用者輸入數字,返回值為n
if [ -z "$n" ] ---當為空時
then
echo "Please input a number." --提示請輸入值
exit 1 --退出,當用戶執行完指令碼執行echo$? 的時候會返回1
fi
n1=`echo $n|sed 's/[0-9]//g'` --輸出是否為純數字,如果是數字,則清空,賦值給$n1
if [ -n "$n1" ] --判斷$n1是否為空(即$n1不是純數字)
then
echo "Please input a number." --為空再次提示輸入數字
exit 1 --退出
fi
if [ $n -lt 60 ] && [ $n -ge 0 ] ---當數值小於60 且大於等於0 提示tag1
then
tag=1
elif [ $n -ge 60 ] && [ $n -lt 80 ] ---當數值大於等於60並且小於80 提示tag2
then
tag=2
elif [ $n -ge 80 ] && [ $n -lt 90 ] ---當數值大於等於80且小於90 提示tag3
then
tag=3
elif [ $n -ge 90 ] && [ $n -le 100 ] ---當數值大於等於90且小於100 提示tag4
then
tag=4
else
tag=0
fi
case $tag in --當你的tag值為1/2/3/4、的時候執行如下
1)
echo "not ok" ---tag1提示not ok
;;
2)
echo "ok" --tag2提示 ok
;;
3)
echo "ook" -tag3提示 ook
;;
4)
echo "oook" ---tag4提示 oook
;;
*) --除此之外的執行tag=0
echo "The number range is 0-100." --提示重新輸入數值範圍為0-100
;;
esac
執行結果100
執行結果101:提示不在此範圍
執行過程
20.10 for迴圈
案例1
1. 編寫for迴圈指令碼:計算1到100所有數字和
[[email protected] ~]# vi for1.sh # 新增內容 :
#!/bin/bash
sum=0
for i in `seq 1 100`
do
echo "$sum + $i"
sum=$[$sum+$i]
echo $sum
done
echo $sum
2. 執行for1.sh指令碼 :[[email protected] ~]# sh for1.sh
案例2
1. 檔案列表迴圈(常用)
[[email protected] ~]# vim for2.sh # 新增內容:
#!/bin/bash
cd /etc/
for a in ls /etc/
do
if [ -d $a ] # 判斷是否是目錄,且存在
then
echo $a
ls $a
fi
done
2. 執行for2.sh指令碼:
[[email protected] ~]# sh -x for2.sh
[[email protected] ~]# for i in `ls ./`; do echo $i ; done
20.11 while迴圈(上)
語法: while 條件; do 內容… ; done
1. 每隔30秒檢查系統負載,當負載達到10,發一份郵件 !
[[email protected] ~]# vim while1.sh 新增內容:
#!/bin/bash
while true #可以寫成 while :
do
load=`w|head -1|awk -F 'load average: ' '{print $2}'|cut -d. -f1`
if [ $load -gt 10 ]
then
/usr/local/sbin/mail.py [email protected] "load load" "$load"
fi
sleep 30
done
2. 執行while1.sh指令碼 :[[email protected] ~]# sh -x while1.sh #顯示每步執行結果
20.12 while迴圈(下)
1. 讓使用者不斷的輸入純數字,才停止換算 !
[[email protected] ~]# vim while2.sh # 新增內容:
#!/bin/bash
while :
do
read -p "Please input a number: " n
if [ -z "$n" ] --表示當變數的值為空時會怎麼樣
then
echo "you need input sth."
continue
fi
n1=`echo $n|sed 's/[-0-9]//g'`
if [ -n "$n1" ] --表示當變數的值不為空
then
echo "you just only input numbers."
continue
fi
break
done
echo $n
2. 執行while2.sh指令碼 :[[email protected] ~]# sh -x while2.sh
20.13 break跳出迴圈
1. break跳出迴圈 :
[[email protected] ~]# vim break.sh # 新增內容 :
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
break
fi
echo $i
done
echo aaaaa
2. 執行break.sh指令碼 :
[[email protected] ~]# sh -x break.sh
[[email protected] ~]# sh break.sh
執行過程:可以看到當i=3就跳出以下迴圈,直接運aaaaa結束
20.14 continue結束本次迴圈
1. continue結束本次迴圈 :
[[email protected] ~]# vim continue.sh # 新增內容:
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
continue
fi
echo $i
done
echo aaaaa
2. 執行continue.sh指令碼 :[[email protected] ~]# sh continue.sh
執行過程:可以看到一個3,就沒了。continue僅僅跳出本次迴圈,繼續下一次迴圈
20.15 exit退出整個指令碼
1. exit直接退出整個指令碼 :
[[email protected] ~]# vim exit.sh新增內容:
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
exit
fi
echo $i
done
echo aaaaa
2. 執行exit.sh指令碼 :[[email protected] ~]# sh exit.sh
執行過程:當i=3 直接退出指令碼