目錄html
1、shell腳本介紹
2、shell腳本結構和執行
3、date命令用法
4、shell腳本中的變量
5、hell腳本中的邏輯判斷
6、文件目錄屬性判斷
7、if特殊用法
8、case判斷
9、for循環
10、while循環
11、break跳出循環
12、continue結束本次循環
十3、exit退出整個腳本
十4、擴展linux
shell是一種腳本語言, 是用戶與內核進行交互的一種接口。shell
shell可使用邏輯判斷、循環等語法,也能夠自定義函數。編程
shell是系統命令的集合vim
shell腳本能夠實現自動化運維,能大大增長咱們的運維效率bash
shell腳本一般在編輯器中編寫,由命令及其註釋組成,註釋是跟在#號後的內容,用來對腳本進行解釋。less
第一行 位於腳本左上角的第一行會指出由哪一個程序來執行腳本中的行。這一行一般稱爲shbang,寫做#!/bin/bash運維
一個bash shell程序由一組unix/linux命令、bash命令、程序結構控制語句和註釋組成編輯器
爲便於區分,通常以.sh結尾。函數
例如:
#!/bin/bash # Scriptname: greet for name in $* # same as for name in $@ do echo Hi $name done
shell的執行方式有二種
//執行方式1 [root@localhost sh]# vim greet.sh [root@localhost sh]# chmod u+x greet.sh [root@localhost sh]# ./greet.sh kennminn Hi kennminn 或者 [root@localhost sh]# chmod u+x greet.sh [root@localhost sh]# pwd /root/script/sh [root@localhost sh]# /root/script/sh/greet.sh kennminn Hi kennminn //執行方式2 [root@localhost sh]# bash greet.sh kennminn Hi kennminn
查看腳本的執行過程 bash -x script-name
[root@localhost sh]# bash -x greet.sh kennminn + for name in '$*' + echo Hi kennminn Hi kennminn
查看腳本是否有語法錯誤
//沒有語法錯誤時 [root@localhost sh]# bash -n greet.sh kennminn //將最後一行的done刪掉 [root@localhost sh]# vim greet.sh #!/bin/bash # Scriptname: greet for name in $* # same as for name in $@ do echo Hi $name [root@localhost sh]# bash -n greet.sh kennminn greet.sh: line 7: syntax error: unexpected end of file
date命令打印系統日期和時間。
[root@localhost sh]# date Sun Jul 29 21:08:24 EDT 2018
經常使用格式
命令 | 含義 |
---|---|
date +%Y | 年(4位) |
date +%y | 年(2位) |
date +%m | 月 |
date +%d | 日 |
date +%D | 以月/日/年格式顯示日期 |
date +%F | 以年-月-日格式顯示日期 |
date +%H | 小時 |
date +%M | 分鐘 |
date +%S | 秒 |
date +%T | 以時:分:秒格式顯示時間,等於date +%H:%M:%S |
date +%s | 時間戳表示距離1970年1月1日到現的秒數 |
date +%w | 這個星期的第幾周 |
date +%W | 今年的第幾周 |
date +%h | 月份縮寫,等於date +%b |
date -d "-1 day" | 一天前 |
date -d "+1 day" | 一天後 |
date -d "-1 year" | 一年前 |
date -d "-1 month" | 一個月前 |
date -d "-1 hour" | 一小時前 |
date -d "-1 min" | 一分鐘前 |
eg:
//顯示日期 [root@localhost sh]# date +%Y-%m-%d 2018-07-29 [root@localhost sh]# date +%F 2018-07-29 [root@localhost sh]# date +%D 07/29/18 //顯示時間 [root@localhost sh]# date +%H:%M:%S 09:22:23 [root@localhost sh]# date +%T 09:22:30 //顯示時間戳 [root@localhost sh]# date +%s 1532913790 //顯示1天后的日期 [root@localhost sh]# date -d "+1 day" Tue Jul 31 09:24:16 CST 2018 //顯示1天前的日期 [root@localhost sh]# date -d "-1 day" Sun Jul 29 09:24:43 CST 2018 //顯示1小時前的時間 [root@localhost sh]# date -d "-1 hour" +%T 08:25:43 //將時間戳以日期格式顯示 [root@localhost sh]# date -d @1532913790 Mon Jul 30 09:23:10 CST 2018 //顯示指定日期的時間戳 [root@localhost sh]# date +%s -d "2018-06-23" 1529683200 //顯示日曆 [root@localhost sh]# cal July 2018 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 //顯示指定月的日曆 [root@localhost sh]# cal 7 17 July 17 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
變量就是爲某個信息片斷所起的名字,標誌內存中的一段地址。
當腳本中使用某個字符串較頻繁而且字符串長度很長時就應該使用變量代替
使用條件語句時,常使用變量 if [ $a -gt 1 ]; then ... ; fi
引用某個命令的結果時,用變量替代 n=wc -l 1.txt
或者n=$(wc -l 1.txt)
寫和用戶交互的腳本時,變量也是必不可少的 read -p "Input a number: " n; echo $n 若是沒有指定變量名n,默認變量名爲REPLY
內置變量 $0, $1, $2… $0表示腳本自己,$1 第一個參數,$2 第二個 .... $#表示參數個數,
$*表示獲取當前shell腳本全部傳參的個數,不加引號和$@相同,加上引號則將全部的參數視爲單個字符串。至關於」$1 $2 $3」。
$@表示獲取當前shell腳本全部傳參的參數,不加引號和$*相同。若是給$@加上雙引號,例如」$@」,則表示將全部的參數視爲不一樣的獨立字符串,至關於」$1」,」$2」,」$3」….這是將多參數傳遞給其餘程序的最佳方式,由於它會保留全部的內嵌在每一個參數裏的任何空白。當」$@」和」$*」都加雙引號時,二者是有區別的,都不加雙引號,二者無區別。
變量有環境變量和用戶自定義變量
用戶自定義變量變量名能夠由一個字母、數字或下劃線符號組成,不能以數字開頭。長度不超過20個字符。變量名區分大小寫,請留意:Var1 和var1不是同一個變量。
例如:
//等號(=)兩端不能有空格 //引用變量值的方式:在變量名前加$ [root@localhost sh]# name=terry [root@localhost sh]# echo $name terry [root@localhost sh]# name =terry -bash: name: command not found
shell中只能進行整數運行,若是須要進行浮點數,須要藉助bc命令
整數運算語法
1.$[ ]
[root@localhost sh]# n=5;echo $[$n+1] 6
2.$(())
[root@localhost sh]# n=5;echo $(($n+1)) 6 [root@localhost sh]# n=5;echo $((n+1)) 6
3.(())
[root@localhost sh]# ((n+=1));echo $n 6
4.expr
//注意+號兩邊要有空格 [root@localhost sh]# expr 4 + 5 9 [root@localhost sh]# r=`expr 4 + 5` [root@localhost sh]# echo $r 9
5.let
[root@localhost sh]# let n=n+1 [root@localhost sh]# echo $n 1
格式1:if 條件 ; then 語句; fi
[root@localhost sh]# vim if1.sh #!/bin/bash a=3 if [ $a -gt 2 ] then echo ok! fi [root@localhost sh]# chmod u+x if1.sh [root@localhost sh]# ./if1.sh ok! 或者 [root@localhost sh]# a=3;if [ $a -gt 2 ]; then echo ok! ; fi ok!
格式2:if 條件; then 語句; else 語句; fi
[root@localhost sh]# vim if2.sh #!/bin/bash a=1 if [ $a -gt 2 ] then echo ok! else echo It\'s no ok! fi [root@localhost sh]# ./if2.sh It's no ok! [root@localhost sh]# sh -x ./if2.sh + a=1 + '[' 1 -gt 2 ']' + echo 'It'\''s' no 'ok!' It's no ok!
格式3:if …; then … ;elif …; then …; else …; fi
[root@localhost sh]# vim if3.sh #/bin/bash a=2 if [ $a -eq 3 ];then echo The number is three. elif [ $a -gt 3 ];then echo the number is great then three. else echo the number is less then three. fi [root@localhost sh]# chmod u+x if3.sh [root@localhost sh]# ./if3.sh the number is less then three. [root@localhost sh]# sh -x ./if3.sh + a=2 + '[' 2 -eq 3 ']' + '[' 2 -gt 3 ']' + echo the number is less then three. the number is less then three.
test命令的數值比較功能
比較 | 描述 |
---|---|
n1 -eq n2 | 檢查n1是否等於n2 |
n1 -ge n2 | 檢查n1是否大於等於n2 |
n1 -gt n2 | 檢查n1是否大於n2 |
n1 -le n2 | 檢查n1是否小於等於n2 |
n1 -lt n2 | 檢查n1是否小於n2 |
n1 -ne n2 | 檢查n1是否不等於n2 |
test命令的字符串比較
比較 | 描述 |
---|---|
str1 = str2 | 檢查str1和str2是否相等 |
str1 != str2 | 檢查str1和str2是否不相等 |
str1 < str2 | 檢查str1是否比str2小 |
str1 > str2 | 檢查str1是否比str2大 |
可使用 && ||結合多個條件
if [ $a -gt 5 ] && [ $a -lt 10 ] &&表示而且
if [ $b -gt 5 ] || [ $b -lt 3 ] ||表示或者
文件比較
比較 | 描述 |
---|---|
-d file | 檢查文件是否存且是一個目錄 |
-e file | 檢查文件是否存在 |
-f file | 檢查文件是否存且是一個文件 |
-r file | 檢查文件是否存在且可讀 |
-s file | 檢查文件是否存在且非空 |
-w file | 檢查文件是否存在並可寫 |
-x file | 檢查文件是否存在並可執行 |
-o file | 檢查文件是否存在並屬當前用戶全部 |
-G file | 檢查文件是否存在而且默認組與當前用戶相同 |
file1 -nt file2 | 檢查file1是否比file2新 |
file1 -ot file2 | 檢查file1是否比file2舊 |
[root@localhost sh]# vim file1.sh #/bin/bash f1='/tmp/tt.txt' if [ -f $f1 ];then echo "$f exist" else touch $f1 fi //第一次文件不存在時 [root@localhost sh]# sh -x file1.sh + f1=/tmp/tt.txt + '[' -f /tmp/tt.txt ']' + touch /tmp/tt.txt //第二次文件已經存在 [root@localhost sh]# sh -x file1.sh + f1=/tmp/tt.txt + '[' -f /tmp/tt.txt ']' + echo ' exist' exist //判斷文件目錄是否存在 [root@localhost sh]# cp file1.sh file2.sh [root@localhost sh]# vim file2.sh #/bin/bash f1='/tmp/tt.txt' if [ -f $f1 ];then echo "$f exist" fi [root@localhost sh]# ./file2.sh exist //判斷文件是否可讀 [root@localhost sh]# cp file2.sh file3.sh [root@localhost sh]# vim file3.sh #/bin/bash f1='/tmp/tt.txt' if [ -r $f1 ];then echo "$f is readable" fi [root@localhost sh]# ./file3.sh is readable
比較 | 描述 |
---|---|
-n str2 | 檢查str1的長度是否非0 |
-z str2 | 檢查str1的長度是否爲0 |
[root@localhost sh]# vim file4.sh #!/bin/bash file='/tmp/tt.txt' if [ -n "$file" ];then echo "the file $file is not empty" fi [root@localhost sh]# ./file4.sh the file /tmp/tt.txt is empty
其餘特殊用法
使用命令來作判斷條件
//-q表示靜默模式 //grep命令匹配其返回值是0,若是沒有匹配則返回值是非0 [root@localhost sh]# if grep -q 'hjm' /etc/passwd;then echo user exist;fi user exist
使用! 在參數前 表示取反 [ ! -e file ] 表示文件不存在
中括號中不能使用<,>,==,!=,>=,<=這樣的符號
語法:
case 變量名 in value1) command ;; value2) command ;; *) commond ;; esac
在case程序中,能夠在條件中使用|,表示或的意思, 好比
a|b) command ;;
eg
[root@kun05 shell]# vim case1.sh #!/bin/bash read -p "Please input number: " n #讓用戶輸入數字 if [ -z "$n" ] then echo "Please input number: " exit 1 fi #判斷用戶是否沒填數字 n1=`echo $n|sed 's/[0-9]//g'` if [ ! -z "$n1" ] then echo "Please input number: " exit 1 fi #判斷用戶是否填純數字 if [ $n -lt 60 ] then tag=1 elif [ $n -ge 60 ] && [ $n -lt 80 ] then tag=2 elif [ $n -ge 80 ] && [ $n -lt 90 ] then tag=3 elif [ $n -ge 90 ] && [ $n -le 100 ] then tag=4 else tag=0 fi #給分數賦值給tag case $tag in 1) echo "bu ji he" ;; 2) echo "liang hao" ;; 3) echo "you xiu" ;; 4) echo "fei chang bang" ;; *) echo "The number range is 0-100" ;; esac [root@localhost sh]# vim grade.sh [root@localhost sh]# sh -x ./grade.sh + read -p 'Please input number: ' n Please input number: 60 + '[' -z 60 ']' ++ echo 60 ++ sed 's/[0-9]//g' + n1= + '[' '!' -z '' ']' + '[' 60 -lt 60 ']' + '[' 60 -ge 60 ']' + '[' 60 -lt 80 ']' + tag=2 + case $tag in + echo 'liang hao' liang hao
語法格式
for 變量名 in 條件; do …; done
eg
//計算1到100的和 [root@localhost sh]# vim sum.sh #!/bin/bash result=0 for i in $(seq 1 100) do result=$((result+i)) done echo $result [root@localhost sh]# chmod u+x sum.sh [root@localhost sh]# ./sum.sh 5050 //遍歷/etc目錄並把目錄列出來 [root@localhost sh]# vim for2.sh #!/bin/bash cd /etc for file in * do [ -d $file ] && ls $file done [root@localhost sh]# chmod u+x for2.sh [root@localhost sh]# ./for2.sh | more abrt-action-save-package-data.conf abrt.conf gpg_keys.conf plugins ld libnssckbi.so.x86_64 mta mta-aliasesman ...下略
語法格式
while 條件; do … ; done
eg
//每隔30秒查看系統負載,當大於10時發郵件 [root@localhost sh]# vim while1.sh #!/bin/bash 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 coco44566@163.com "load high" "$load" fi sleep 30 done [root@localhost sh]# chmod u+x while1.sh [root@localhost sh]# sh -x while1.sh + : ++ w ++ cut -d . -f1 ++ awk -F 'load average: ' '{print $2}' ++ head -1 + load=0 + '[' 0 -gt 10 ']' + sleep 30 : ture 1 都是表明爲正 所以while : 就是一個死循環 爲了避免讓while腳本不意外終止 可使用screen命令 再到screen下執行此腳本 //提示讓用戶只能輸入數字 [root@localhost sh]# vim while2.sh #!/bin/bash while : do read -p "Please input a number: " n if [ -z "$n" ] then echo "Please input sth!" continue fi ##判斷用戶是否直接回車 n1=`echo $n|sed 's/[0-9]//g'` if [ -n "$n1" ] then echo "Please input number!" continue fi #判斷用戶是否輸入純數字 echo $n break done [root@localhost sh]# sh while2.sh Please input a number: a Please input number! Please input a number: v Please input number! Please input a number: 1 1 echo $n|sed 's/[0-9]//g 把數字替換爲空,再來判斷剩下的內容
eg
[root@kun05 shell]# 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 aaaa [root@localhost sh]# chmod u+x break.sh [root@localhost sh]# ./break.sh [root@localhost sh]# ./break.sh 1 1 2 2 3 aaaa
忽略本次循環,直接進行下一次循環
eg
[root@localhost sh]# mv break.sh continue.sh [root@localhost sh]# 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 aaaa [root@localhost sh]# ./continue.sh 1 1 2 2 3 4 4 5 5 aaaa
eg
[root@localhost sh]# mv continue.sh exit.sh [root@localhost sh]# vim exit.sh #!/bin/bash for i in $(seq 1 5) do echo $i if [ $i -eq 3 ] then exit 1 fi echo $i done echo aaaa [root@localhost sh]# ./exit.sh 1 1 2 2 3
總結:
break,continue都是在for while循環中使用的
break出現時候會跳出本次循環 直接忽略掉了break後面的代碼
continue出現時候也會忽略掉了continue後面的代碼並從新再來執行循環
exit直接跳出腳本 通常exit 後面會跟一個數字 給用戶返回該值
select用法
http://www.apelearn.com/bbs/thread-7950-1-1.html