天天看點

【Linux雲計算架構:第一階段-Linux作業系統入門到精通】第20章——條件判斷和流程控制語句If

本節所講内容:

20.1 read指令鍵盤讀取變量的值

20.2 流程控制語句if

20.3 test測試指令

20.4 流程控制過程中複雜條件和通配符

20.5 實戰-3個shell腳本實戰

20.1 read指令鍵盤讀取變量的值

從鍵盤讀取變量的值,通常用在shell腳本中與使用者進行互動的場合。該指令可以一次讀取多個變量的值,​​

​變量和輸入的值都需要使用空格隔開。​

​​在read指令後面,如果沒有指定變量名,讀取的資料将被自動指派給特定的變量REPLY

read從鍵盤讀入資料,賦給變量

例1:

[root@xuegod63 ~]# read a b
hello world
[root@xuegod63 ~]# echo $a $b
hello world      

2.1.1 read常用見用法及參數

例1:從标準輸入讀取一行并指派給變量passwd

[root@xuegod63 ~]# read passwd      

例2:讀取多個值,從标準輸入讀取一行,直至遇到第一個空白符或換行符。把使用者鍵入的第一個詞存到變量first中,把該行的剩餘部分儲存到變量last中

[root@xuegod63 ~]# read firt last
aaaa  bbbb      

例3:read -s passwd 将你輸入的東西隐藏起來,值賦給passwd。這個使用者隐藏密碼資訊

[root@xuegod63 ~]# read -s passwd
[root@xuegod63 ~]# echo $passwd
123456      

例4:輸入的時間限制

[root@xuegod63 ~]# read -t 2 time   #超過兩秒沒有輸入,直接退出      

例5:輸入的長度限制

[root@xuegod63 ~]# read -n 2 test  #最多隻接受2個字元      

例6:使用-r參數輸,允許讓輸入中的内容包括:空格、/、\、 ?等特殊字元串。

[root@xuegod63 ~]# read  -r line
sdf sdf / sdfs /n
[root@xuegod63 ~]# echo $line
sdf sdf / sdfs /n      

例7:-p 用于給出提示符,在前面的例子中我們使用了echo –n “…“來給出提示符

方法1:

[root@xuegod63 ~]# read -p  "please input: "  pass
please input: 123456
[root@xuegod63 ~]# echo $pass
123456      

方法2:

[root@xuegod63 ~]# echo -n "please input: " ; read pass
please input: 123456     
[root@xuegod63 ~]# echo $pass
123456      

例8:read 綜合執行個體

[root@xuegod63 ~]# vim  test-read.sh  #寫入以下内容
#!/bin/bash
read -p "請輸入姓名:" NAME
read -p "請輸入年齡:" AGE
read -p "請輸入性别:" SEX

cat<<eof
*********************
你的基本資訊如下:
姓名: $NAME
年齡:$AGE
性别:$SEX
********************
eof

[root@xuegod63 ~]# sh test-read.sh
請輸入姓名:xuegod
請輸入年齡:111
請輸入性别:man
*********************
你的基本資訊如下:
姓名: xuegod
年齡:111
性别:man      

20.2 流程控制語句if

20.2.1 文法格式:

if  條件   
  then
   commands
  fi
if語句流程圖:      
【Linux雲計算架構:第一階段-Linux作業系統入門到精通】第20章——條件判斷和流程控制語句If

注:根據我們的指令退出碼來進行判斷(echo $? =0),如果是0,那麼就會執行then後面的指令

例1:

[root@xuegod63 ~]# vim  if-1.sh 
#!/bin/bash
if ls /mnt
then
  echo "it's ok"
fi

[root@xuegod63 ~]# bash !$
bash if-1.sh
CentOS_BuildTag  GPL     LiveOS    RPM-GPG-KEY-CentOS-7
EFI    images    Packages  RPM-GPG-KEY-CentOS-Testing-7
EULA     isolinux  repodata  TRANS.TBL
it's ok      

20.2.2 雙分支if語句

文法格式:

if command  ; then
    commands
else
    commands
fi      
【Linux雲計算架構:第一階段-Linux作業系統入門到精通】第20章——條件判斷和流程控制語句If

例2:

[root@xuegod63 ~]# cat if-2.sh
#!/bin/bash
if grep root /etc/passwd ; then
        echo "it's ok"
else
        "it's err"
fi 

[root@xuegod63 ~]# sh if-2.sh 
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
it's ok      

例3:

[root@xuegod63 ~]# cat if-3.sh
#!/bin/bash

if grep xuegod /etc/passwd ;then
  echo "it's ok"
else
  echo "it's err"
fi

[root@xuegod63 ~]# sh if-3.sh
it's err      

20.2.3 多分支if語句

文法結構:

if條件測試操作1 ; then
    commands
elif  條件測試操作2  ; then
    commands
elif 條件測試操作3 ; then
    commands
.......
else
    commands
fi      
【Linux雲計算架構:第一階段-Linux作業系統入門到精通】第20章——條件判斷和流程控制語句If

例4:判斷使用者在系統中是否存在,是否有家目錄

[root@xuegod63 ~]# cat if-4.sh
#!/bin/bash
read -p "input a user:" tu
if grep $tu /etc/passwd ; then
        echo "the user $tu exists on this system"
elif ls -d /home/$tu  ;  then
        echo "the user $tu not exists on this system"
        echo "$tu has a home directory"
else
        echo "the user $tu not exists on this system"
        echo "$tu not has a direcotry"
fi

[root@xuegod63 ~]# sh if-4.sh 
Input a user: hr
chrony:x:994:990::/var/lib/chrony:/sbin/nologin
hr:x:1000:1000:hr:/home/hr:/bin/bash
the user hr exists on this system

[root@xuegod63 ~]# sh if-4.sh
Input a user: xuegod
/home/xuegod
xuegod has a directory      

20.3 test測試指令

Shell中的 test 指令用于檢查某個條件是否成立,它可以進行數值、字元和檔案三個方面的測試

格式:test 測試條件

如果結果是對的,也叫結果為真,用$?=0表示,反之為假,用非0表示。

可用 [ $a 條件 $b ] 來作為條件判斷,注:括号中間要加空格

20.3.1 數值比較

【Linux雲計算架構:第一階段-Linux作業系統入門到精通】第20章——條件判斷和流程控制語句If

例1:比較大小

[root@xuegod63 ~]# cat test1.sh 
#!/bin/bash
if test 2 -eq 1  ; then
        echo ok
else
        echo err
fi

if [ 2 -eq 2 ]  ; then
        echo ok
else
        echo err
fi      

例2: 比較整數大小

[root@xuegod63 ~]# cat test2.sh 
#!/bin/bash
read -p "input var1 var2:" var1 var2
if [ $var1 -gt $var2  ] ;  then
        echo "$var1 > $var2"
elif [ $var1 -lt $var2 ] ; then
        echo "$var1 < $var2"
else
        echo "$var1 = $var2"
fi
注意:在做數值比較時,隻能用整數      

20.3.2 字元串比較

【Linux雲計算架構:第一階段-Linux作業系統入門到精通】第20章——條件判斷和流程控制語句If

例1:根據使用者名判斷是否是超級管理者

[root@xuegod63 ~]# cat test3.sh
#!/bin/bash
read -p  "input your name: " name
if [ $name == "root" ] ; then
        echo "you are super administrator"
else
        echo  "You are a general user"
fi
  
[root@xuegod63 ~]# bash test3.sh 
input your name: root
you are super administrator
[root@xuegod63 ~]# bash test3.sh 
input your name: mk
You are a general usero "You are a general user"      

例2:在做字元串大小比較的時候,注意字元串的順序

大于号和小于号必須轉義,要不然SHELL會把它當成重定向符号
大于和小于它們的順序和sort排序是不一樣的
在test比較測試中,它使用的是ASCII順序,大寫字母是小于小寫字母的;sort剛好相反      

擴充: ASCII(American Standard Code for Information Interchange,美國資訊交換标準代碼)是基于拉丁字母的一套電腦編碼系統,主要用于顯示現代英語和其他西歐語言。它是現今最通用的單位元組編碼系統,并等同于國際标準ISO/IEC 646。

【Linux雲計算架構:第一階段-Linux作業系統入門到精通】第20章——條件判斷和流程控制語句If
[root@xuegod63 ~]# cat test4.sh 
#!/bin/bash
var1=test
var2=Test
if [  $var1 \>  $var2  ] ; then
        echo "$var1 > $var2"
else
        echo "$var1 < $var2"
fi 
[root@xuegod63 ~]# bash test4.sh 
test > Test      

20.3.3 檔案比較

【Linux雲計算架構:第一階段-Linux作業系統入門到精通】第20章——條件判斷和流程控制語句If

例1:

[root@xuegod63 ~]# vim  test5.sh 
#!/bin/bash
if [ -e /etc/passwd ] ; then
        echo ok
else
        echo err
fi 

[root@xuegod63 ~]# bash test5.sh 
ok      

例2:

[root@xuegod63 ~]# test -e /etc/aaa.txt && echo ok || echo err
err
[root@xuegod63 ~]# test -e /etc/passwd && echo ok || echo err
ok
[root@xuegod63 ~]# test -e /etc && echo ok || echo err
ok      

例:清空日志目錄

[root@xuegod63 ~]# cat clear-log.sh 
#!/bin/bash
# clear /var/log/messages

#确定目前是root使用者
if [ $USER != "root" ];then
  echo "你必須使用root使用者才能執行腳本"
  exit 10    #直接退出,并傳回10
fi

#判斷檔案是否存在
if [ ! -f /var/log/messages ];then
  echo "檔案不存在"
  exit 12
fi

#保留最近100行的日志内容
tail -100 /var/log/messages > /var/log/mesg.tmp

#日志清理
>/var/log/messages
#cat /dev/null > /var/log/messages

mv /var/log/mesg.tmp /var/log/messages
echo "Logs clean up"
注:退出碼 exit ,取值範圍是0-255      

例: exit 退出bash,并傳回一個值

[root@xuegod63 ~]# ssh 192.168.1.63
[email protected]'s password: 123456
Last login: Mon May 28 20:37:41 2018 from xuegod63.cn
[root@xuegod63 ~]# 
[root@xuegod63 ~]# exit 10      

登出

Connection to 192.168.1.63 closed.
[root@xuegod63 ~]# echo $?
10      

20.4 流程控制過程中複雜條件和通配符

20.4.1 判斷第一種:兩個條件都為真或有一個為真就執行

if [ 條件判斷一 ] && (||) [ 條件判斷二 ]; then    
   指令一
elif [ 條件判斷三 ] && (||) [ 條件判斷四 ]; then
    指令二  
else
    執行其它
fi      

判斷第二種

if [條件判斷一 -a (-o) 條件判斷二 -a (-o) 條件判斷三]; then
elif [條件判斷三  -a (-o) 條件判斷四 ]; then
else
   執行其它
fi      

判斷第三種

if [[條件判斷一 && (||) 條件判斷二 ]]; then
elif [[ 條件判斷三 && (||) 條件判斷四 ]]; then
else
   執行其它
fi      

例1:設定umask

參考: ​

​[root@xuegod63 ~]# vim /etc/profile​

【Linux雲計算架構:第一階段-Linux作業系統入門到精通】第20章——條件判斷和流程控制語句If
[root@xuegod63 ~]# vim  umask.sh 
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
    echo "umask 002"
else
    echo "i am root :umask 022"
fi
[root@xuegod63 ~]# bash umask.sh 
i am root :umask 022      

例2:[[ 。。。 ]]和[ 。。。]的差別

[[… ]] 運算符是[… ]運算符的擴充;[[… ]]能夠支援 *,< 、>等符号且不需要轉義符      

例1:

[root@xuegod63 ~]# if [[ $USER == r* ]] ; then echo "hello,$USER" ; else echo $USER not ; fi
hello,root
注: $USER == r*對比時,  r* 表示以r開頭的任意長度字元串,這樣就包括root      

當隻有一個[] 方括号時:

[root@xuegod63 ~]# if [ $USER == r* ] ; then echo "hello,$USER" ; else echo $USER not ; fi
root not
#對比時r* ,就表示兩個字元串 r*      

也可以這樣寫:

[root@xuegod63 ~]# if [[ $USER == [a-z]oot ]] ; then echo "hello,$USER" ; else echo $USER not ; fi      

[[ 。。。 ]]和[ 。。。]的差別彙總:

1、所有的字元與邏輯運算符直接用“空格”分開,不能連到一起。
2、在[… ]表達式中,常見的> 、<需要加轉義符\,大小比較
3、進行邏輯運算符&& 、||比較時;如果用的[ ]符号,則用在外面,如[… ] && [… ] || [ …]如果在[…]裡面進行邏輯與或的比較,則用-a、-o進行表示,如[ x = y –a x < z –o x > m ]
4、[[… ]] 運算符隻是[… ]運算符的擴充;能夠支援< 、>符号運算不需要轉義符;它還是以字元串比較大小。裡面支援邏輯運算符 || 、 && , 不再使用-a 、-o
5、[[…]] 用 && 而不是 -a 表示邏輯“與”;用 || 而不是 -o表示邏輯“或”
6、[[… ]]可以進行算術擴充,而[ ... ]不可以
7、[[...]]能用正則,而[...]不行
8、雙括号((  ))用于數學表達式
9、雙方括号号[[  ]]用于進階字元串處理,比如“模糊比對”      

20.4.2 shell中的通配符

shell常見通配符:

【Linux雲計算架構:第一階段-Linux作業系統入門到精通】第20章——條件判斷和流程控制語句If

例:

[root@xuegod63 ~]#  ls /etc/*.conf
[root@xuegod63 ~]# ls /etc/???.conf
/etc/nfs.conf  /etc/sos.conf  /etc/yum.conf
[root@xuegod63 ~]# touch  /opt/a{1,2,3}.txt
[root@xuegod63 ~]# ls /opt/a[123].txt
/opt/a1.txt  /opt/a2.txt  /opt/a3.txt
[root@xuegod63 ~]# ls /opt/a[1,2,3].txt
[root@xuegod63 ~]# ls /opt/a[13].txt
/opt/a1.txt  /opt/a3.txt      

20.5 實戰-3個shell腳本實戰

20.5.1 實戰1:編寫腳本檢查伺服器運作狀态

[root@xuegod63 ~]# vim status.sh
#!/bin/bash
if [ $# -ge 1 ] ; then
        systemctl status $1 > /dev/null
   if [ $? -eq 0 ] ; then
        echo "$1 服務正在運作"
   else
        systemctl start $1
   fi
else
          echo "執行腳本的格式"
          echo "sh $0 服務名"
fi      

20.5.2 實戰2:根據學生的成績判斷 學生的優劣

[root@xuegod63 ~]# vim  check_cj.sh  
#!/bin/bash
read  -p   "請輸入你的成績  "   cj
if   [ $cj   -ge  0  ]    &&  [  $cj  -le  59  ]  ;then
     echo   "補考"
elif  [  $cj  -ge  60 ]    &&  [  $cj  -le  70   ]   ;then
    echo  "良好"
elif     [ $cj -ge 71 ]     &&  [ $cj   -le  85 ]   ;then
   echo  "好"
elif [ $cj  -ge 86 ]     &&  [   $cj  -le  100 ]   ;then
    echo  "優秀" 
else
   echo "成績的有效範圍是0-100之間"
fi      

20.5.3 實戰3:每周一晚上3:00 ,備份資料庫伺服器上webdb庫的所有資料到系統的/mysqlbak目錄裡,使用系統日期做備份檔案名。

[root@xuegod63 ~]# vim   mysqlbak.sh
#!/bin/bash
baknamefile=`date +%Y-%m-%d`
bakdir=/mysqlbak
user=root
password=123
dbname=webdb
[  -e  $bakdir   ]   ||    mkdir    $bakdir
mysqldump   -u$user   -p$password  --flush-logs  $dbname   >    $bakdir/${baknamefile}-webdb.sql      
[root@xuegod63 ~]# vim etcbak.sh
#!/bin/bash
baknamefile=`date +%Y-%m-%d`
bakdir=/etcbak
srcdir=/etc
[  -e  $bakdir   ]   ||    mkdir    $bakdir
tar zcvf ${bakdir}/${baknamefile}-etc.tar.gz /etc/
echo "========================"
ls -lh ${bakdir}/${baknamefile}-etc.tar.gz
echo "back etc is ok!"

[root@xuegod63 ~]# chmod +x  etcbak.sh

[root@xuegod63 ~]# crontab  -e
0 3 * * *  /root/etcbak.sh  2>&1 > /dev/null