天天看點

shell中的條件判斷與控制流程條件判斷

條件判斷

1.按照檔案類型進行判斷

測試選項 作用
-b 檔案 判斷該檔案是否存在,并且是否為塊裝置檔案(是塊裝置檔案則為真)
-c 檔案 判斷檔案是否存在,并且是否為字元裝置檔案(是字元裝置檔案為真)
-d 檔案 判斷檔案是否存在,并且是否為目錄檔案(是目錄則為真)
-e 檔案 判斷檔案是否存在(存在為真)
-f 檔案 判斷檔案是否存在,并且是否為普通檔案(是普通檔案則為真)
-L 檔案 判斷檔案是否存在,并且是否為符号連結檔案(是符号連結檔案為真)
-p 檔案 判斷檔案是否存在,并且是否為管道檔案(是管道檔案則為真)
-s 檔案 判斷檔案是否存在,并且是否為空(非空為真)
-S 檔案 判斷檔案是否存在,且是否為套接字檔案(是套接字檔案為真)

判斷式有兩種格式(通常使用後一種):

test -e /etc/profile

[ -e /etc/profile ](中括号和條件判斷式之間一定要有空格!)

例如,執行:

[ -e /etc/profile ] && echo yes || echo no

執行結果為 yes

2.按檔案權限判斷

測試選項 作用
-r 檔案 檔案存在且擁有讀權限為真
-w 檔案 檔案存在且有寫權限為真
-x 檔案 檔案存在且擁有執行權限為真
-u 檔案 檔案存在且擁有SUID權限為真
-g 檔案 檔案存在且擁有SGID權限為真
-k 檔案 檔案存在且擁有SBIT權限為真

例如執行:

[ -w /etc/profile ] && echo yes || echo no結果為yes

這裡要注意:權限測試并不區分是哪一個使用者的權限,隻要存在一個使用者有相應的權限即為真。

3.比較兩個檔案

測試選項 作用
檔案1 -nt檔案2 判斷檔案1的修改時間是否比檔案2新(新,則為真)
檔案1 -ot檔案2 判斷檔案1的修改時間是否比檔案2舊(舊,則為真)
檔案1 -ef檔案2 判斷檔案1是否和檔案2的lnode号一緻,可以了解為判斷兩個檔案是否為同一個檔案。這個判斷可用于判斷硬連結。

例如,執行:

ln /home/hunan/student.txt /home/hunan/bin/stu.txt

[ /home/hunan/student.txt -ef /home/hunan/bin/stu.txt ] && echoyes || echo no

上述指令先是建立了一個硬連結,然後判斷指向的檔案是否相同,結果為:yes

4.比較兩個整數

測試選項 作用
整數1 -eq整數2 整數1等于整數2為真
整數1 -ne整數2 整數1不等于整數2為真
整數1 -gt整數2 整數1大于整數2為真
整數1 -lt整數2 整數1小于整數2為真
整數1 -ge整數2 整數1大于等于整數2為真
整數1 -le整數2 整數1小于等于整數2為真

例如,執行:

$[ 23 -gt 22 ] && echo yes || echo no

yes

$[ 23 -lt 22 ] && echo yes || echo no

no

5.比較兩個字元串

測試選項 作用
-z 字元串 字元串為空傳回真
-n 字元串 字元串非空傳回真
字元串1==字元串2 字元串1和字元串2相等傳回真
字元串1!=字元串2 字元串1和字元串2不相等傳回真

例如,執行:

$name=mike

$[ -z $name ] && echo yes || echo no

no

$[ $name == mike ] && echo yes || echo no

yes

6.shell中的與,或,非

測試選項 作用
判斷式1 -a判斷式2 邏輯與
判斷式1 -o判斷式2 邏輯或
! 判斷式 邏輯非

例如,執行:

$aa=11

$[ -n $aa -a "$aa" -gt 22 ] && echo yes || echo no

no

控制流程

1.單分支if條件語句

if [ 條件判斷式 ];then
    程式
fi
           

或者

if [ 條件判斷式 ]
    then
        程式
fi
           

注意:

1.要記得以fi結尾/2.條件判斷式和中括号之間必須有空格/3.如果then和if在同一行要以 ; 分隔。

示例1:判斷目前使用者是否為root使用者。思路:用env輸出所有環境變量,用grep提取出USER變量,用cut将USER=XXX以“=”為分隔符切分,取切分後的第二個字元串即為目前使用者名。指令之間以管道連接配接。

腳本内容:

#!/bin/bash
#提取出使用者名指派給test變量
test=$(env| grep USER | cut -d "=" -f 2)
if [ $test == "root" ];then
<span style="white-space:pre">	</span>echo "this is root login."
fi
           

注意:要給腳本執行權限才能執行( chmoda+x *.sh )。

示例2:判斷分區使用率。當根分區使用率大于某一門檻值,給出警告。思路:

df -h | grep sda4 | awk '{print $5}'| cut -d "%" -f 1

df -h列印分區資訊,我這裡的根分區挂在在sda4,用grep過濾出這一行,用awk列印出第五部分,在用cut切掉%号。即可得到使用率數值。

腳本内容:

#!/bin/bash
#提取出目前根分區的使用率
test=$(df -h | grep sda4 | awk '{print $5}' | cut -d "%" -f 1)
if [ "$test" -gt 30 ];then
    echo "/ is full!"
fi
           

(這裡為了展現程式作用,門檻值取 30%. )

2.雙分支if語句

if[條件判斷式 ]
    then
        條件成立時執行語句
    else
        條件不成立時執行語句
fi
           

示例3:使用者輸入一個路徑,程式判斷是否為一個目錄。思路:用read指令讀取使用者輸入,用-d判斷是否為目錄。

腳本内容:

#!/bin/bash
read -t 30 -p "請輸入路徑:" path
if [ -d $path ];then
    echo "is directory!"
else
    echo "not directory!"
fi
           

示例4:判斷apache服務是否啟動。思路:用psaux列出所有程序,過濾出含有httpd但是不含grep的程序(因為grephttpd指令也會産生一個含有httpd的程序)

腳本内容:

#!/bin/bash
test=$(ps aux | grep httpd | grep -v grep)
#如果字元串不為空
if [ -n $test ]
	then
		echo “$(date) httpd is ok” >> /tmp/autostart-acc.log
	else
		echo “$(date) restart httpd !!” >> /tmp/autostart-err.log
		/etc/rc.d/init.d/httpd start
fi
           

注意:這種方法,腳本名中不能含有httpd!

3.多分支if語句

if [ 條件判斷式1 ]
	then
		當條件判斷式1成立,執行語句
elif [ 條件判斷式2 ]
	then
		當條件判斷式2成立,執行語句
             . . . 省略 . . .
else
	當所有條件判斷式都不成立,執行語句
fi
           

示例 5 :判斷輸入的檔案類型

腳本内容:

#!/bin/bash
#讀入使用者輸入的路徑
read -t 30 -p 請輸入路徑名: path
if [ -z $path ]
	then
		echo 請輸入路徑。
		exit 1
elif [ ! -e $path ]
	then
		echo 您輸入的路徑不存在!
		exit 2
elif [ -f $path ]
	then
		echo 您輸入的是普通檔案。
elif [ -d $path ]
	then
		echo 您輸入的是目錄。
else
	echo 您輸入的是其它檔案。
fi
           

4. 多分支 case 語句

case $變量名 in
	“值1”)
		如果變量的值等于值1,則執行程式1
		;;
	“值2”)
		如果變量的值等于值2,則執行程式2
		;;
	. . . 省略其它分支 . . .
	*)
		如果變量的值都不是以上的值,則執行此程式
	;;
esac
           

注意:每次選擇之後都要加上“雙分号”!除了最後的 * 其它的值都要被雙引号引起來。

示例6:根據使用者輸入做出不同反應。

#!/bin/bash
  read -t 30 -p '請輸入你的選擇 yes/no:' cho
  case $cho in
           "yes")
                   echo 你的選擇是yes
                   ;;
           "no")
                   echo 你的選擇是no
                   ;;
          *)
                  echo 你的選擇是其它。
                  ;;
  esac
           

5.for循環

文法1:

for  變量 in 值1 值2 值3...
	do
		程式
	done
           

示例 7 :循環列印數字

#!/bin/bash
for i in 1 2 3 4 5
	do
		echo $i
	done
           

示例 8 :批量解壓縮

#!/bin/bash
cd /root/test
for i in $(ls *.tar.gz *.gz)
	do
		tar -zxf $i
	done
           

文法 2 :

for ((初始值; 循環空值條件; 變量變化))
	do
		程式
	done
           

示例 9 :計算 1+2+...+100

#!/bin/bash
   s=0
   for ((i=1; i<=100; i=i+1))
           do
                   s=$(($s+$i))
           done
   echo $s
           

6.while循環

while [ 條件判斷式 ]
	do
		程式
	done
           

示例10:用while循環計算1+2+...+100

#!/bin/bash
   s=0
   i=1
   while [ $i -le 100 ]
           do
                   s=$(($i+$s))
                   i=$(($i+1))
           done
   echo "the sum is:"$s
           

7.until 循環

until循環和while循環相反,until循環時隻要條件判斷式不成立則繼續循環,一旦條件判斷式成立則停止循環。

until [ 條件判斷式 ]
	do
		程式
	done
           

示例11:用until循環計算1+2+...+100

#!/bin/bash
   s=0
   i=1
   until [ $i -gt 100 ]
           do
                   s=$(($s+$i))
                   i=$(($i+1))
           done
   echo 'the sum is:'$s