1. 程式人生 > >20.5 shell腳本中的邏輯判斷 20.6 文件目錄屬性判斷 20.7 if特殊用法 20.8/20.9 case判斷

20.5 shell腳本中的邏輯判斷 20.6 文件目錄屬性判斷 20.7 if特殊用法 20.8/20.9 case判斷

腳本 shell 文件目錄 邏輯判斷

- 20.5 shell腳本中的邏輯判斷
- 20.6 文件目錄屬性判斷
- 20.7 if特殊用法
- 20.8/20.9 case判斷
# 20.5 Shell腳本中的邏輯判斷
- 很多腳本可以直接用命令執行,比如之前的那個
```
[root@aming-01 ~]# for i in `seq 1 5`;do echo $i;done
1
2
3
4
5
[root@aming-01 ~]# for i in `seq 1 5`
> do
> echo $i
> done
1
2
3
4
5
[root@aming-01 ~]# 
```
- 格式1:if 條件 ; then 語句; fi
- 下面來寫個腳本
- a=5 ,如果a 大於3 就 打印 ok
- 如果寫成一行就 下面這樣
```
[root@aming-01 ~]# a=5
[root@aming-01 ~]# if [ $a -gt 3 ]
> then
> echo ok
> fi
ok
[root@aming-01 ~]# 

[root@aming-01 ~]# if [ $a -gt 3 ];then echo ok; fi
ok
[root@aming-01 ~]# 

```
- 用腳本的形式編輯下,就是
```
[root@aming-01 shell]# vi if1.sh

#!/bin/bash
a=5
if [ $a -gt 3 ]
then 
    echo ok 
fi
~                                                                                         
~                                                                                         
~                                                                                         
                                                                                       
~                                                                                         
:wq

[root@aming-01 shell]# sh if1.sh
ok
[root@aming-01 shell]# 

```
- 格式2:if 條件; then 語句; else 語句; fi
- 如果滿足條件怎麽樣,不滿足又會怎麽樣
```
[root@aming-01 shell]# cp if1.sh if2.sh
[root@aming-01 shell]# vi if2.sh

#!/bin/bash
a=1
if [ $a -gt 3 ]
then
    echo ok
else
    echo not ok
fi
                                                                                        
~                                                                                         
~                                                                                         
~                                                                                         
:wq

[root@aming-01 shell]# sh -x if2.sh
+ a=1
+ ‘[‘ 1 -gt 3 ‘]‘
+ echo not ok
not ok
[root@aming-01 shell]# 

```
- 格式3:if …; then … ;elif …; then …; else …; fi
- -gt 指的是大於  -lt指的是小於
```
[root@aming-01 shell]# cp if2.sh if3.sh
[root@aming-01 shell]# vi if3.sh

#!/bin/bash
a=5
if [ $a -gt 1 ]
then
    echo ">1"
elif [$a -lt 6 ]
then 
    echo "<6 && >1" 
else
    echo not ok
fi
~                                                                                         
                                                                                       
~                                                                                         
~                                                                                         
:wq
[root@aming-01 shell]# vi if3.sh

[root@aming-01 shell]# cat if3.sh
#!/bin/bash
a=5
if [ $a -gt 1 ]
then
    echo ">1"
elif [$a -lt 6 ]
then 
    echo "<6 && >1" 
else
    echo not ok
fi
[root@aming-01 shell]# 

[root@aming-01 shell]# sh -x if3.sh
+ a=5
+ ‘[‘ 5 -gt 1 ‘]‘
+ echo ‘>1‘
>1
[root@aming-01 shell]# 
```
- 改下
```
[root@aming-01 shell]# vi if3.sh

#!/bin/bash
a=5
if [ $a -gt 4 ]
then
    echo ">1"
elif [ $a -lt 6 ]
then
    echo "<6 && >1"
else
    echo not ok
fi
~                                                                                         
                                                                                      
~                                                                                         
:wq
[root@aming-01 shell]# sh -x if3.sh
+ a=5
+ ‘[‘ 5 -gt 4 ‘]‘
+ echo ‘>1‘
>1
[root@aming-01 shell]# 
```
- if 判斷的三種格式
```
[root@aming-01 shell]# if ...;then ...; fi^C
[root@aming-01 shell]# if ...;then ...;else ...;fi^C
[root@aming-01 shell]# if ...;thn ...;elif ...then ...;else ...;fi^C
[root@aming-01 shell]# 
```
- 邏輯判斷表達式:if [ $a -gt $b ]; if [ $a -lt 5 ]; if [ $b -eq 10 ]等 -gt (>); -lt(<); -ge(>=); -le(<=);-eq(==); -ne(!=) 註意到處都是空格

-    gt 大於        lt 小於         eq 等於
-   -ge 大於等於   -le小於等於     -ne 不等於
```
[root@aming-01 shell]# gt lt eq   -ne -ge -le ^C
```
- 可以使用 && || 結合多個條件         &&並且   ||或者
-  if [ $a -gt 5 ] && [ $a -lt 10 ]; then
-  if [ $b -gt 5 ] || [ $b -lt 3 ]; then










# 20.6 文件目錄屬性判斷
- shell中 我們通常和文件、目錄打交道,所以對文件目錄的判斷很重要
- if 判斷文件、目錄屬性
- [ -f file ]判斷是否是普通文件,且存在
- 舉例
```
Last login: Tue Nov 21 19:49:55 2017
[root@aming-01 ~]# vi file1.sh

#!/bin/bash
f="/tmp/aminglinux"
if [ -f $f ]
then
    echo $f exist
else 
    touch $f
fi
~                                                                                         
~                                                                                         
                                                                                        
~                                                                                         
:wq
[root@aming-01 ~]# vi file1.sh
[root@aming-01 ~]# sh -x file1.sh
+ f=/tmp/aminglinux
+ ‘[‘ -f /tmp/aminglinux ‘]‘
+ touch /tmp/aminglinux
[root@aming-01 ~]# 

```
- 解釋:首先f回去判斷這個文件到底存在與否,很明顯不存在,於是就創建了一個/tmp/aminglinux 文件
- 那我們再次執行這個腳本,很明顯這個文件已經存在了,所以echo  /tmp/aminglinux  exist
```
[root@aming-01 ~]# sh -x file1.sh
+ f=/tmp/aminglinux
+ ‘[‘ -f /tmp/aminglinux ‘]‘
+ echo /tmp/aminglinux exist
/tmp/aminglinux exist
[root@aming-01 ~]# 
```
- 這裏把這個腳本移到shell/目錄下面來,以為腳本文件我們統一放在/shell 目錄裏
```
[root@aming-01 ~]# ls
aming.txt  anaconda-ks.cfg  file1.sh  shell  zabbix-release-3.2-1.el7.noarch.rpm
[root@aming-01 ~]# cd shell/
[root@aming-01 shell]# mv /root/file1.sh .
[root@aming-01 shell]# ls
01.sh  file1.sh  if1.sh  if2.sh  if3.sh
```
-  [ -d file ] 判斷是否是目錄,且存在
```
[root@aming-01 shell]# cp file1.sh file2.sh
[root@aming-01 shell]# vi file2.sh

#!/bin/bash
f="/tmp/aminglinux"
if [ -d $f ]
then
    echo $f exist
else
    touch $f
fi
~                                                                                         
~                                                                                         
                                                                                       
~                                                                                         
:wq
[root@aming-01 shell]# vi file2.sh
[root@aming-01 shell]# sh -x file2.sh
+ f=/tmp/aminglinux
+ ‘[‘ -d /tmp/aminglinux ‘]‘
+ touch /tmp/aminglinux
[root@aming-01 shell]#
```
- 很明顯他不適目錄,不適目錄就touch 一個目錄


- 還有一種情況,我不管它是文件還是目錄,我僅僅是想知道這個文件或者目錄到底存在不存在
- [ -e file ] 判斷文件或目錄,是否存在
```
[root@aming-01 shell]# vi file2.sh

#!/bin/bash
f="/tmp/aminglinux"
if [ -e $f ]
then
    echo $f exist
else
    touch $f
fi
~                                                                                         
~                                                                                         
                                                                                       
:wq
[root@aming-01 shell]# vi file2.sh
[root@aming-01 shell]# sh -x file2.sh
+ f=/tmp/aminglinux
+ ‘[‘ -e /tmp/aminglinux ‘]‘
+ echo /tmp/aminglinux exist
/tmp/aminglinux exist
[root@aming-01 shell]# 
```
- 判斷這個目錄或者文件是否存在,不存在就創建一個目錄或者文件
- 如果這個文件存在touch會是摸一下 文件或者目錄,改變文件和目錄的 三個time值 Atime  Ctime  Mtime

-  [ -r file ] 判斷文件是否可讀

```
[root@aming-01 shell]# vi file2.sh

#!/bin/bash
f="/tmp/aminglinux"
if [ -r $f ]
then
    echo $f readable
fi
~                                                                                         
                                                                                         
~                                                                                         
:wq
[root@aming-01 shell]# vi file2.sh

[root@aming-01 shell]# sh file2.sh
/tmp/aminglinux readable
[root@aming-01 shell]# 
```
- 顯示這個文件是可讀的
 
- [ -w file ] 判斷文件是否可寫
```
[root@aming-01 shell]# vi file2.sh

#!/bin/bash
f="/tmp/aminglinux"
if [ -w $f ]
then
    echo $f writeable
fi
~                                                                                         
~                                                                                         
~                                                                                         
                                                                                        
~                                                                                         
:wq

[root@aming-01 shell]# vi file2.sh
[root@aming-01 shell]# !sh
sh file2.sh
/tmp/aminglinux writeable
[root@aming-01 shell]# 

```
- 文件可寫
- 可讀可寫可執行是針對當前用戶root 來說的
```
[root@aming-01 shell]# ls -l /tmp/aminglinux
-rw-r--r-- 1 root root 0 11月 21 20:09 /tmp/aminglinux
[root@aming-01 shell]# 
```
-  [ -x file ] 判斷文件是否可執行
```
[root@aming-01 shell]# vi file2.sh

#!/bin/bash
f="/tmp/aminglinux"
if [ -x $f ]
then
    echo $f exeable
fi
~                                                                                         
                                                                                        
~                                                                                         
:wq
[root@aming-01 shell]# vi file2.sh
[root@aming-01 shell]# sh file2.sh
[root@aming-01 shell]# 
```
- 因為它不可執行,所以沒有任何的輸出
- 因為我們根本就沒有定義else
```
[root@aming-01 shell]# cat file2.sh
#!/bin/bash
f="/tmp/aminglinux"
if [ -x $f ]
then
    echo $f exeable
fi
[root@aming-01 shell]# 
```
- 這樣用的比較多
- 常用案例
並且
```
f="/tmp/aminglinux"
[ -f $f ] && rm -f $f     //前一條命令執行成功才會繼續執行之後的命令

等同於下面的表達方式
if [ -f $f ]     
then
      rm -rf $f
fi
```

- 或者
```
f="/tmp/aminglinux"
[ -f $f ] || touch $f    //前面命令不成功時,執行後面的命令
if [ ! -f $f ]        //  “!”表示了如果這條命令不成功,就往下執行 (!表示取反)
then
      touch $f
fi
```








# 20.7 if特殊用法
- if [ -z "$a" ] 這個表示當變量a的值為空時會怎麽樣
```
[root@aming-01 shell]# vi if4.sh

#!/bin/bash
n=`wc -l /tmp/lalal`
if [ $n -gt 100 ]
then
    echo alsdflljk
fi
                                                                                       
~                                                                                         
:wq
[root@aming-01 shell]# vi if4.sh
[root@aming-01 shell]# sh -x if4.sh
++ wc -l /tmp/lalal
wc: /tmp/lalal: 沒有那個文件或目錄
+ n=
+ ‘[‘ -gt 100 ‘]‘
if4.sh: 第 3 行:[: -gt: 期待一元表達式
[root@aming-01 shell]#
```
- 當變量沒有值的時候 會報錯,為了讓這個腳本更加嚴謹,應該做一些判斷
- if [ -z "$a" ] 這裏表示當變量a的值為空時 就echo error 並且 exit
```
[root@aming-01 shell]# vi if4.sh

#!/bin/bash
n=`wc -l /tmp/lalal`
if [ -z "$n" ]
then
    echo error
    exit
elif  [ $n -gt 100 ]
then
    echo alsdflljk
fi
~                                                                                         
                                                                                         
:wq


[root@aming-01 shell]# vi if4.sh
[root@aming-01 shell]# sh -x if4.sh
++ wc -l /tmp/lalal
wc: /tmp/lalal: 沒有那個文件或目錄
+ n=
+ ‘[‘ -z ‘‘ ‘]‘
+ echo error
error
+ exit
[root@aming-01 shell]# 

```
- 再改進一下,這樣它就不再報錯了
```
[root@aming-01 shell]# !vi
vi if4.sh

#!/bin/bash
if [ ! -f /tmp/lalal ]
then
   echo "/tmp/lalal not exist."
   exit
fi
n=`wc -l /tmp/lalal`
if [ -z "$n" ]
then
    echo error
    exit
elif  [ $n -gt 100 ]
then
    echo alsdflljk
fi
~                                                                                         
                                                                                        
~                                                                                         
:wq

[root@aming-01 shell]# sh if4.sh
/tmp/lalal not exist.
[root@aming-01 shell]# 

```
-  if [ -n "$a" ] 表示當變量a的值不為空
-  用變量的時候 要用雙引號引起來,如果是一個文件,那就不用了
-  - 這個 [ -n "$a" ]  是可以判斷文件的,判斷一個文件的內容是否不為空,條件成立
```
[root@aming-01 shell]# ls
01.sh  file1.sh  file2.sh  if1.sh  if2.sh  if3.sh  if4.sh
[root@aming-01 shell]# if [ -n 01.sh ]; then echo ok;fi
ok
[root@aming-01 shell]# 
```
- 同樣可以判斷變量
- 解釋:當變量b 不為空,那麽echo $b, 否則 當變量b為空,那麽echo b is null,這裏變量b 是為空的
- -n 和 -z 用法,如果不是變量,不需要雙引號“”;因為這兩個是針對文件執行的;
```
[root@aming-01 shell]# echo $b

[root@aming-01 shell]# if [ -n "$b" ]; then echo $b; else echo "b is null"; fi
b is null
[root@aming-01 shell]# 
```
- 比如判斷系統的用戶裏面是否有user1這個用戶
```
[root@aming-01 ~]# useradd user1 
[root@aming-01 ~]# cd shell
[root@aming-01 shell]# grep -w ‘user1‘ /etc/passwd
user1:x:1011:1011::/home/user1:/bin/bash
[root@aming-01 shell]# 
```
- 表示如果/etc/passwd中含有‘user1‘的字符 時會怎麽樣
-  -w 更加精準的匹配,只匹配‘’內的單詞
-  如果/etc/passwd 裏包含user1 ,那麽就說 user1 exist  user1 存在
```
[root@aming-01 shell]# if grep -w ‘user1‘ /etc/passwd;then echo "user1 exist";fi
user1:x:1011:1011::/home/user1:/bin/bash
user1 exist
[root@aming-01 shell]# 
```
- 只不過這個判斷的過程 是會輸出 過濾的語句出來,把這個結果給輸出出來,grep -q 僅僅是做一個過濾,但是不會吧過濾的內容顯示出來
```
[root@aming-01 shell]# if grep -wq ‘user1‘ /etc/passwd;then echo "user1 exist";fi
user1 exist
[root@aming-01 shell]# 
```
- 反過來怎麽表示呢,如果這個user1不存在
- 如果user1 不存在,加個! 表示取反的意思,那麽useradd user1
- 只不過這個操作過程不成立的,因為user1本身就存在了 後面這個命令不生效的then "useradd user1"
```
[root@aming-01 shell]# if ! grep -wq ‘user1‘ /etc/passwd;then "useradd user1";fi
[root@aming-01 shell]# 
```
-  if [ ! -e file ]; then 表示文件不存在時會怎麽樣
- if (($a<1)); then …等同於 if [ $a -lt 1 ]; then…

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







# 20.8 case判斷(上)
```
- 格式 case  變量名 in 
                     value1)
                          command
                          ;;
                     value2)
                          command
                          ;;
                      *)
                        commond
                            ;;
                      esac
``` 
- 在case程序中,可以在條件中使用|,表示或的意思, 比如 
```
2|3) 
    command
    ;;
```
- shell腳本案例:
```
[root@aming-01 shell]# vi case.sh


                                                                                       
~                                                                                         
"case.sh" [New File]
```
- 加入以下腳本
```
[root@aming-01 shell]# vi case.sh
#!/bin/bash
read -p "Please input a number: " n
if [ -z "$n" ]

then
    echo "Please input a number."
    exit 1
fi

n1=`echo $n|sed ‘s/[0-9]//g‘`
if [ -n "$n1" ]
then
 echo "Please input a number."
 exit 1
fi

if [ $n -lt 60 ] && [ $n -ge 0 ]
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

case $tag in
    1)
        echo "not ok"
        ;;
    2)
        echo "ok"
        ;;
    3)
        echo "ook"
        ;;
    4)
        echo "oook"
        ;;
    *)
        echo "The number range is 0-100."
        ;;
esac

```
- 腳本命令解釋
- read -p "Please input a number: " n
if [ -z "$n" ]   
- read -p 的作用,n作為你要捕獲一個變量的名字,用戶輸入什麽數值,最終這個n 這個變量就會賦值什麽東西
```
[root@aming-01 shell]# read -p "Please input a number: " n
Please input a number: 
Please input a number; kdkdk
[root@aming-01 shell]# echo $n
kdkdk
[root@aming-01 shell]# 
[root@aming-01 shell]# echo $n
123
[root@aming-01 shell]# 
```
- if [ -z "$n" ] 表示當用戶沒有輸入東西的時候  為空的時候  if [ -z "$n" ] 表示為空的時候,說明用戶沒有輸入,那奧告訴他 echo "Please input a number." 請輸入一個數字
- 這裏的 exit 1  ,這個1 表示 當一個命令一個語句運行完之後 都會有一個返回的值,echo $? 輸出結果為0 表示命令 語句是正確的,如果是1 那就是錯誤 這裏的exit 1 就是那個echo $?的輸出的值

-  n1=`echo $n|sed ‘s/[0-9]//g‘`
if [ -n "$n1" ] 
- 這裏的變量判斷的時你輸入的字符串 是不是純數字,萬一輸入的時1a1 或者 純字母aaa呢,都需要去判斷下,如果不是那就要做一個操作,把裏面的數字做一個清空
- 當你的變量不為空時,if [ -n "$n1" ] 表示$n1不為空時,繼續提示讓你輸入一個純數字
```
n1=`echo $n|sed ‘s/[0-9]//g‘`
if [ -n "$n1" ]
then
 echo "Please input a number."
 exit 1
```









# 20.9 case判斷(下)
```
fi

if [ $n -lt 60 ] && [ $n -ge 0 ]
then
    tag=1
```
- 當你輸入的時數字的時候,數字滿足[ $n -ge 0 ] 大於等於0  並且 [ $n -lt 60 ]小於60,那麽作為標記1  tag1 是個變量

- 如果不是上述情況
```
elif [ $n -ge 60 ] && [ $n -lt 80 ]
then
    tag=2
```
- [ $n -ge 60 ]是大於等於60 並且 [ $n -lt 80 ]小於80 那麽作為標簽2 
- 同理
```
elif [ $n -ge 80 ]  && [ $n -lt 90 ]
then
    tag=3
```
- 如果n滿足[ $n -ge 80 ] 大於等於80 並且  [ $n -lt 90 ] 小於90 為標簽3

- 同理
```
elif [ $n -ge 90 ] && [ $n -le 100 ]
then
    tag=4
```
- 如果n [ $n -ge 90 ]大於等於90 並且  [ $n -le 100 ]小於等於100 ,為標簽4
- 同理

```
else 
    tag=0
```
- 除此之外 標記 標簽0
- case格式
```
case $tag in
    1)
	echo "not ok"
        ;;
    2)
        echo "ok"
        ;;
    3)
        echo "ook"
        ;;
    4)
        echo "oook"
        ;;
    *)
        echo "The number range is 0-100."
        ;; 
```
- 滿足標簽1 輸出 not ok
- 滿足標簽2 輸出 ok
- 滿足標簽3 輸出 ook
- 滿足標簽4 輸出 oook
- 其他不再這個範圍內 輸出  "The number range is 0-100." 數字範圍為0-100
- 下面來測試下腳本 分別輸入不同的數字 或者 其他來測試下
- 比如數字101,提示數字範圍在0-100
```
[root@aming-01 shell]# sh case.sh
Please input a number: 101
The number range is 0-100.
[root@aming-01 shell]# 
```
- 來看下它的執行過程
```
[root@aming-01 shell]# sh -x case.sh
+ read -p ‘Please input a number: ‘ n
Please input a number: 101
+ ‘[‘ -z 101 ‘]‘
++ echo 101
++ sed ‘s/[0-9]//g‘
+ n1=
+ ‘[‘ -n ‘‘ ‘]‘
+ ‘[‘ 101 -lt 60 ‘]‘ 
+ ‘[‘ 101 -ge 60 ‘]‘
+ ‘[‘ 101 -lt 80 ‘]‘
+ ‘[‘ 101 -ge 80 ‘]‘
+ ‘[‘ 101 -lt 90 ‘]‘
+ ‘[‘ 101 -ge 90 ‘]‘
+ ‘[‘ 101 -le 100 ‘]‘
+ tag=0
+ case $tag in
+ echo ‘The number range is 0-100.‘
The number range is 0-100.
[root@aming-01 shell]# 
```
- 首先判斷101這個變量存在不存在,存在繼續往下走
- 之後做一個判斷,存在把數字清空,最後n1為空 
- 判斷它是否不為空,不為空那就正常,正常的話那就往下走,做一個判斷
- 101是否小於60 
- 101是否大於等於60
- 101是否小於80
- 101是否大於等於80
- 101是否小於90
- 101是否大於等於90
- 101是否小於等於100
- 這些條件都不滿足,所以tag= 0 所以提示  ‘The number range is 0-100.‘數字範圍在0-100

- 如果輸入78 輸出ok
```
[root@aming-01 shell]# sh -x case.sh
+ read -p ‘Please input a number: ‘ n
Please input a number: 78
+ ‘[‘ -z 78 ‘]‘
++ echo 78
++ sed ‘s/[0-9]//g‘
+ n1=
+ ‘[‘ -n ‘‘ ‘]‘
+ ‘[‘ 78 -lt 60 ‘]‘
+ ‘[‘ 78 -ge 60 ‘]‘
+ ‘[‘ 78 -lt 80 ‘]‘
+ tag=2
+ case $tag in
+ echo ok
ok
[root@aming-01 shell]# 
```
- 如果輸入88 ,輸出ook
```
[root@aming-01 shell]# sh -x case.sh
+ read -p ‘Please input a number: ‘ n
Please input a number: 88
+ ‘[‘ -z 88 ‘]‘
++ echo 88
++ sed ‘s/[0-9]//g‘
+ n1=
+ ‘[‘ -n ‘‘ ‘]‘
+ ‘[‘ 88 -lt 60 ‘]‘
+ ‘[‘ 88 -ge 60 ‘]‘
+ ‘[‘ 88 -lt 80 ‘]‘
+ ‘[‘ 88 -ge 80 ‘]‘
+ ‘[‘ 88 -lt 90 ‘]‘
+ tag=3
+ case $tag in
+ echo ook
ook
[root@aming-01 shell]# 
```
- 如果輸入一個不是數字的,提示輸入一個數字
```
[root@aming-01 shell]# sh -x case.sh
+ read -p ‘Please input a number: ‘ n
Please input a number: dkkddkdk112
+ ‘[‘ -z dkkddkdk112 ‘]‘
++ echo dkkddkdk112
++ sed ‘s/[0-9]//g‘
+ n1=dkkddkdk
+ ‘[‘ -n dkkddkdk ‘]‘
+ echo ‘Please input a number.‘
Please input a number.
+ exit 1
[root@aming-01 shell]# 

```


20.5 shell腳本中的邏輯判斷 20.6 文件目錄屬性判斷 20.7 if特殊用法 20.8/20.9 case判斷