20.1 shell 腳本介紹html
shell是一種腳本語言linux
可使用邏輯判斷、循環等語法shell
能夠自定義函數vim
shell是系統命令的集合bash
shell腳本能夠實現自動化運維,能大大增長咱們的運維效率運維
20.2 shell 腳本結構和執行ide
開頭須要加 #!/bin/bash,不加開頭在本機上能夠運行,換臺機器就不必定能執行。在行首文件頭處指定接下來要運行的命令是經過哪個解釋器進行操做的。函數
以#開頭的行做爲解釋說明,腳本的名字以 .sh 結尾,用於區分這是一個 shell 腳本優化
執行方法有兩種:spa
一、/bin/bash 實際上就是 /bin/sh
[root@arslinux-01 ~]# ll /bin/sh lrwxrwxrwx. 1 root root 4 3月 14 05:51 /bin/sh -> bash [root@arslinux-01 ~]# ll /bin/bash -rwxr-xr-x. 1 root root 964608 10月 31 2018 /bin/bash
二、給文件執行權限,chmod a+x 1.sh 才能夠 ./1.sh
[root@arslinux-01 shell]# ./1.sh -bash: ./1.sh: 權限不夠 [root@arslinux-01 shell]# chmod a+x 1.sh [root@arslinux-01 shell]# ./1.sh 123 22:43:46 up 2:39, 1 user, load average: 0.10, 0.09, 0.13 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.194.1 20:08 2.00s 2:44 0.00s /bin/bash ./1.sh 1.sh
三、若是沒有權限,能夠 /bin/bash 1.sh
[root@arslinux-01 shell]# /bin/bash 1.sh [root@arslinux-01shell]# /bin/bash 1.sh 123 22:48:59 up 2:44, 1 user, load average: 0.01, 0.05, 0.11 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.194.1 20:08 3.00s 2:51 0.00s /bin/bash 1.sh 1.sh
查看腳本執行過程: bash -x 1.sh
查看腳本是否語法錯誤: bash -n 1.sh
20.3 date 命令用法
[root@arslinux-01 ~]# date 2019年 06月 15日 星期六 23:11:02 CST
date +%Y-%m-%d, date +%y-%m-%d 年月日
[root@arslinux-01 ~]# date +%Y-%m-%d 2019-06-15 [root@arslinux-01 ~]# date +%y-%m-%d 19-06-15 [root@arslinux-01 ~]# date +%Y //年 2019 [root@arslinux-01 ~]# date +%M //分鐘 14 [root@arslinux-01 ~]# date +%D 06/15/19 [root@arslinux-01 ~]# date +%F 2019-06-15 [root@arslinux-01 ~]# date +%S //秒 09 [root@arslinux-01 ~]# date +%s //時間戳,距離 1970.01.01.00:00:00 多少秒 1560611775
date +%H:%M:%S = date +%T 時間
[root@arslinux-01 ~]# date +%H:%M:%S 23:18:23 [root@arslinux-01 ~]# date +%T 23:18:29 [root@arslinux-01 ~]# date +%h 6月 [root@arslinux-01 ~]# date +%m 06
date +%s 時間戳
[root@arslinux-01 ~]# date +%s 1560612094 距離 1970.01.01.00:00:00 多少秒
date +%w, date +%W 星期
[root@arslinux-01 ~]# date +%w //星期幾 6 [root@arslinux-01 ~]# date +%W //幾年的第幾周 23
cal 日曆形式查看日期
[root@arslinux-01 ~]# cal 六月 2019 日 一 二 三 四 五 六 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
date -d "-1 day" 一天前
[root@arslinux-01 ~]# date -d "-1 day" 2019年 06月 14日 星期五 23:26:15 CST [root@arslinux-01 ~]# date -d "-1 day" +%F 2019-06-14
date -d "+1day" 一天後
[root@arslinux-01 ~]# date -d "+1 day" +%F 2019-06-16
date -d "-1 month" 一月前
[root@arslinux-01 ~]# date -d "-1 month" +%F 2019-05-15 [root@arslinux-01 ~]# date -d "-1 year" +%F 2018-06-15 [root@arslinux-01 ~]# date -d "-1 week" +%F 2019-06-08
date -d "-1 min" 一分鐘前
[root@arslinux-01 ~]# date -d "-1 min" +%T 23:28:02
date -d @1504620492 根據時間戳換算成日期
[root@arslinux-01 ~]# date -d @1504620492 2017年 09月 05日 星期二 22:08:12 CST
date +%s -d "2019-09-09 09:09:09" 把具體的日期換算成時間戳
[root@arslinux-01 ~]# date +%s -d "2019-09-09 09:09:09" 1567991349
20.4 shell 腳本中的變量
當腳本中使用某個字符串較頻繁而且字符串長度很長時就應該使用變量代替
使用條件語句時,常使用變量 if [ $a -gt 1 ]; then ... ; fi
引用某個命令的結果時,用變量替代 n=`wc -l 1.txt`
寫和用戶交互的腳本時,變量也是必不可少的 read -p "Input a number: " n; echo $n 若是沒寫這個n,能夠直接使用$REPLY
內置變量 $0, $1, $2… $0表示腳本自己,$1 第一個參數,$2 第二個 .... $#表示參數個數
數學運算a=1;b=2; c=$(($a+$b))或者$[$a+$b]
20.5 shell 腳本中的邏輯判斷
格式1:if 條件;then 語句;fi
[root@arslinux-01 ~]# vim 01.sh #/bin/bash a=5 if [ $a -gt 3 ] then echo ok fi
格式2:if 條件;then 語句;else 語句;fi
[root@arslinux-01 shell]# vim 02.sh
#/bin/bash a=1 if [ $a -gt 3 ] then echo ok else echo not ok fi
[root@arslinux-01 shell]# sh -x 02.sh + a=1 + '[' 1 -gt 3 ']' + echo not ok not ok
格式3:if ...;then ...;elif ...;then ...;else ...;fi
[root@arslinux-01 shell]# vim 03.sh #/bin/bash a=3 if [ $a -gt 4 ] then echo ">4" elif [ $a -lt 6 ] then echo "<6 && >1" else echo not ok fi
[root@arslinux-01 shell]# sh -x 03.sh + a=3 + '[' 3 -gt 4 ']' + '[' 3 -lt 6 ']' + echo '<6 && >1' <6 && >1
[root@arslinux-01 shell]# vim 03.sh #/bin/bash a=5 if [ $a -lt 4 ] then echo "<4" elif [ $a -gt 6 ] then echo ">6" else echo not ok fi
[root@arslinux-01 shell]# sh -x 03.sh + a=5 + '[' 5 -lt 4 ']' + '[' 5 -gt 6 ']' + echo not ok not ok
邏輯判斷表達式:
if [ $a -gt $b ]; -gt (>); 大於
if [ $a -lt 5 ]; -lt(<); 小於
if [ $b -eq 10 ]等 -eq(==); 等於
-le(<=);-ge(>=); -ne(!=) 注意處處都是空格
·若是非要用 > < ,能夠用(( ))
[root@localhost shell]# if (($a>1));then echo ok;fi ok
·可使用 && || 結合多個條件
if [ $a -gt 5 ] && [ $a -lt 10 ]; then 而且
if [ $b -gt 5 ] || [ $b -lt 3 ]; then 或者
20.6 文件目錄屬性判斷
·[ -f file ] 判斷是不是普通文件,且存在
·[ -d file ] 判斷是不是目錄,且存在
·[ -e file ] 判斷文件或目錄是否存在
·[ -r file ] 判斷文件是否可讀
·[ -w file ] 判斷文件是否可寫
·[ -x file ] 判斷文件是否可執行
[ -f file ] 判斷是不是普通文件,且存在
[root@arslinux-01 shell]# vim 04.sh #/bin/bash f="/tmp/arslinux" if [ -f $f ] then echo $f exist. else touch $f fi
[root@arslinux-01 shell]# sh -x 04.sh + f=/tmp/arslinux + '[' -f /tmp/arslinux ']' + touch /tmp/arslinux [root@arslinux-01 shell]# sh -x 04.sh + f=/tmp/arslinux + '[' -f /tmp/arslinux ']' + echo /tmp/arslinux exist. /tmp/arslinux exist.
[ -d file ] 判斷是不是目錄,且存在
[root@arslinux-01 shell]# vim file2.sh #/bin/bash f="/tmp/arslinux" if [ -d $f ] then echo $f exist. else touch $f fi
[root@arslinux-01 shell]# sh -x file2.sh + f=/tmp/arslinux + '[' -d /tmp/arslinux ']' + touch /tmp/arslinux
[ -e file ] 判斷文件或目錄是否存在
[root@arslinux-01 shell]# vim file3.sh #/bin/bash f="/tmp/arslinux" if [ -e $f ] then echo $f exist. else touch $f fi
[root@arslinux-01 shell]# sh -x file3.sh + f=/tmp/arslinux + '[' -e /tmp/arslinux ']' + echo /tmp/arslinux exist. /tmp/arslinux exist.
[ -r file ] 判斷文件是否可讀
[root@arslinux-01 shell]# vim file4.sh #/bin/bash f="/tmp/arslinux" if [ -r $f ] then echo $f readable. fi
[root@arslinux-01 shell]# sh -x file4.sh + f=/tmp/arslinux + '[' -r /tmp/arslinux ']' + echo /tmp/arslinux readable. /tmp/arslinux readable.
[ -w file ] 判斷文件是否可寫
[root@arslinux-01 shell]# vim file4.sh #/bin/bash f="/tmp/arslinux" if [ -w $f ] then echo $f writeable. fi
[root@arslinux-01 shell]# sh -x file4.sh + f=/tmp/arslinux + '[' -w /tmp/arslinux ']' + echo /tmp/arslinux writeable. /tmp/arslinux writeable.
[ -x file ] 判斷文件是否可執行
[root@arslinux-01 shell]# vim file4.sh
#/bin/bash f="/tmp/arslinux" if [ -x $f ] then echo $f exeable. fi
[root@arslinux-01 shell]# sh -x file4.sh + f=/tmp/arslinux + '[' -x /tmp/arslinux ']'
簡單寫法
#!/bin/bash f="/tmp/alex" if [ -f $f ] then rm -f $f fi
能夠不用 if 判斷寫成
#!/bin/bash f="/tmp/alex" [ -f $f ] && rm -f $f
#!/bin/bash f="/tmp/alex" if [ -f $f ] then rm -f $f else touch $f fi
能夠反寫爲
#!/bin/bash f="/tmp/alex" if [ ! -f $f ] then touch $f fi
能夠不用 if 判斷,寫成
#!/bin/bash f="/tmp/alex" [ -f $f ] || touch $f
20.7 if 特殊用法
if [ -z "$a" ] 這個表示當變量 a 的值爲空時會怎麼樣
#!/bin/bash n=`wc -l /tmp/bababa` if [ -z "$n" ] then echo error else if [ $n -gt 100] then echo ok fi fi
能夠優化爲:
#!/bin/bash n=`wc -l /tmp/bababa` if [ -z "$n" ] then echo error exit elif [ $n -gt 100] then echo ok fi
能夠再優化:
#!/bin/bash if [ -f /tmp/babala ] then echo "/tmp/babala isn't exist." exit fi n=`wc -l /tmp/bababa` if [ -z "$n" ] then echo error exit elif [ $n -gt 100] then echo ok fi
if [ -n "$a" ] 表示當變量 a 的值不爲空
[root@arslinux-01 shell]# if [ -n 01.sh ];then echo ok;fi ok [root@arslinux-01 shell]# if [ -n "$b" ];then echo "$b";else echo "b is null";fi b is null
命令能夠做爲判斷結果
if grep -q '123' 1.txt; then 表示若是1.txt中含有'123'的行時會怎麼樣
[root@arslinux-01 shell]# if grep -w 'user1' /etc/passwd;then echo "user1 exist";fi user1:x:1001:1001::/home/user1:/bin/bash user1 exist [root@arslinux-01 shell]# if grep -wq 'user1' /etc/passwd;then echo "user1 exist";fi user1 exist
grep -q 靜默輸出
if [ ! -e file ]; then 表示文件不存在時會怎麼樣
if (($a<1)); then …等同於 if [ $a -lt 1 ]; then…
[ ] 中不能使用<,>,==,!=,>=,<=這樣的符號
20.8/20.9 case 判斷
格式:case 變量名 in
value1)
command
;;
value2)
command
;;
*)
commond
;;
esac
:: 表示一個判斷結束,進入下一個判斷
在case程序中,能夠在條件中使用|,表示或的意思, 好比
2|3)
command
;;
*)除以上全部以外的
shell 腳本案例
#!/bin/bash read -p "Please input a number: " n //從標準輸入讀取輸入並賦值給變量 n if [ -z "$n" ] then echo "Please input a number." exit 1 fi n1=`echo $n|sed 's/[0-9]//g'` //從變量n中將數字替換爲空,若是n1不爲空,則不是純數字,那麼現實輸入一個數字並退出 if [ -n "$n1" ] then echo "Please input a number." exit 1 fi if [ $n -lt 60 ] && [ $n -ge 0 ]//純數字往下接着判斷 then tag=1 //標記tag 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 case $tag in 1) echo "not ok" ;; 2) echo "ok" ;; 3) echo "great" ;; 4) echo "brilliant" ;; *) echo "The number range is 0-100." ;; esac
執行腳本看結果:
輸入符合條件的純數字
[root@arslinux-01 shell]# sh -x case.sh + read -p 'Please input a number: ' n Please input a number: 77 + '[' -z 77 ']' ++ echo 77 ++ sed 's/[0-9]//g' + n1= + '[' -n '' ']' + '[' 77 -lt 60 ']' + '[' 77 -ge 60 ']' + '[' 77 -lt 80 ']' + tag=2 + case $tag in + echo ok ok
輸入含字母的數字組合
[root@arslinux-01 shell]# sh -x case.sh + read -p 'Please input a number: ' n Please input a number: l33l + '[' -z l33l ']' ++ echo l33l ++ sed 's/[0-9]//g' + n1=ll + '[' -n ll ']' + echo 'Please input a number.' Please input a number. + exit 1
輸入大於 100 的數字
[root@arslinux-01 shell]# sh -x case.sh + read -p 'Please input a number: ' n Please input a number: 234 + '[' -z 234 ']' ++ echo 234 ++ sed 's/[0-9]//g' + n1= + '[' -n '' ']' + '[' 234 -lt 60 ']' + '[' 234 -ge 60 ']' + '[' 234 -lt 80 ']' + '[' 234 -ge 80 ']' + '[' 234 -lt 90 ']' + '[' 234 -ge 90 ']' + '[' 234 -le 100 ']' + tag=0 + case $tag in + echo 'The number range is 0-100.' The number range is 0-100.
20.10 for 循環
語法:for 變量名 in 條件; do …; done
案例1
計算1到100數字的和
[root@arslinux-01 shell]# vim for1.sh #!/bin/bash sum=0 for i in `seq 1 100` do sum=$[$sum+$i] done echo $sum
案例2
列出/etc/下的目錄或子目錄
[root@arslinux-01 shell]# sh for2.sh #!/bin/bash/ cd /etc/ for a in `ls /etc/` do if [ -d $a ] then ls -d $a fi done
ls 是用空格或回車做爲分隔符,for 循環以他爲對象,那麼可能會出錯
20.11/20.12 while循環
語法:while 條件; do … ; done
案例1
每隔半分鐘檢查系統負載,當負載大於10時,發郵件
[root@arslinux-01 shell]# vim while.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 xxx@163.com "load high" "$load" fi sleep 30 done
: 表示死循環 或者寫成 while true
案例2
作一個讓人讓用戶不停輸入東西的腳本
[root@arslinux-01 shell]# 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
continue 指繼續從新再來一遍循環
continue 從頭繼續從新再來一遍循環
break 退出 while 循環
20.13 break跳出循環
[root@arslinux-01 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 jjjjj
[root@arslinux-01 shell]# sh -x break.sh ++ seq 1 5 + for i in '`seq 1 5`' + echo 1 1 + '[' 1 -eq 3 ']' + echo 1 1 + for i in '`seq 1 5`' + echo 2 2 + '[' 2 -eq 3 ']' + echo 2 2 + for i in '`seq 1 5`' + echo 3 3 + '[' 3 -eq 3 ']' + break + echo jjjjj jjjjj
本來在 i 爲 3 以前,腳本一直執行到done,而後在從頭循環,而 爲 3 時,之間break跳出循環,
echo aaaaaaa
break 用在循環語句裏,for 也行,while 也行
20.14 continue結束本次循環
忽略continue之下的代碼,直接進行下一次循環
[root@arslinux-01 shell]# 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 jjjjj
[root@arslinux-01 shell]# sh -x continue.sh ++ seq 1 5 + for i in '`seq 1 5`' + echo 1 1 + '[' 1 -eq 3 ']' + echo 1 1 + for i in '`seq 1 5`' + echo 2 2 + '[' 2 -eq 3 ']' + echo 2 2 + for i in '`seq 1 5`' + echo 3 3 + '[' 3 -eq 3 ']' + continue + for i in '`seq 1 5`' + echo 4 4 + '[' 4 -eq 3 ']' + echo 4 4 + for i in '`seq 1 5`' + echo 5 5 + '[' 5 -eq 3 ']' + echo 5 5 + echo jjjjj jjjjj
break會跳出循環,再也不執行循環,而continue會結束本次循環,從頭開始執行循環
20.15 exit退出整個腳本
[root@arslinux-01 shell]# 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 jjjjj
[root@arslinux-01 shell]# sh -x exit.sh ++ seq 1 5 + for i in '`seq 1 5`' + echo 1 1 + '[' 1 -eq 3 ']' + echo 1 1 + for i in '`seq 1 5`' + echo 2 2 + '[' 2 -eq 3 ']' + echo 2 2 + for i in '`seq 1 5`' + echo 3 3 + '[' 3 -eq 3 ']' + exit
break 在跳出後還會執行最後的 echo,而 exit 直接退出
給 exit 定義退出的數字
[root@arslinux-01 shell]# vim exit.sh #!/bin/bash for i in `seq 1 5` do echo $i if [ $i -eq 3 ] then exit 2 fi echo $i done echo jjjjj
[root@arslinux-01 shell]# sh -x exit2.sh ++ seq 1 5 + for i in '`seq 1 5`' + echo 1 1 + '[' 1 -eq 3 ']' + echo 1 1 + for i in '`seq 1 5`' + echo 2 2 + '[' 2 -eq 3 ']' + echo 2 2 + for i in '`seq 1 5`' + echo 3 3 + '[' 3 -eq 3 ']' + exit 2 [root@arslinux-01 shell]# echo $? 2
continue 結束本次循環,繼續循環,忽略後面的代碼
break 結束整個循環,跳出
exit 直接退出整個腳本
擴展