2018-07-26 第三十一次課

第三十一次課 shell編程(一)

目錄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


1、shell腳本介紹

shell是一種腳本語言, 是用戶與內核進行交互的一種接口。shell

shell可使用邏輯判斷、循環等語法,也能夠自定義函數。編程

shell是系統命令的集合vim

shell腳本能夠實現自動化運維,能大大增長咱們的運維效率bash


2、shell腳本結構和執行

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的執行方式有二種

  • chmod u+x greet.sh; ./sh 或絕絕對路徑執行
  • bash greet.sh
//執行方式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


3、date命令用法

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


4、shell腳本中的變量

變量就是爲某個信息片斷所起的名字,標誌內存中的一段地址。

當腳本中使用某個字符串較頻繁而且字符串長度很長時就應該使用變量代替

使用條件語句時,常使用變量    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


5、hell腳本中的邏輯判斷

格式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 ] ||表示或者


6、文件目錄屬性判斷

文件比較

比較 描述
-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


7、if特殊用法

比較 描述
-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 ] 表示文件不存在

中括號中不能使用<,>,==,!=,>=,<=這樣的符號


8、case判斷

語法:

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


9、for循環

語法格式

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
...下略


10、while循環

語法格式

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 把數字替換爲空,再來判斷剩下的內容


11、break跳出循環

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


12、continue結束本次循環

忽略本次循環,直接進行下一次循環

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


十3、exit退出整個腳本

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 後面會跟一個數字 給用戶返回該值


十4、擴展

select用法

http://www.apelearn.com/bbs/thread-7950-1-1.html

相關文章
相關標籤/搜索