Linux Shell編程之二選擇結構

Shell編程學習之二編程

1、bash的條件測試bash

    測試方法或者說測試書寫:socket

test EXPRide

[ EXPR ]函數

` EXPR `學習

    例如:測試變量 User_Name 的之是否爲root測試

    test $User_Name="root"
spa

    [ $User_Name == "root" ]rest

    [[ $User_Name == "root" ]orm


    根據比較時操做數的類型,測試類型分爲:

測試類型 運算符 運算符所表明的意義 示例
×××測試

-gt -lt -ge -le 

-eq -ne

-gt 大於  -lt 小於

-ge 大於或等於  -le 小於或等於

-eq 等於  -ne 不等於

都是雙目運算符:

[ $num -gt 3 ]

test $num -ne $sum

[[ $num -ne 0 ]]

字符測試 == =~ > < !=

== 等於   >大於    < 小

!= 不等於   =~ 模式匹配 

都是雙目運算符:

[ $num == "root"]

test $num > $sum

[[ "$num" =~ /bin/bash$ ]]

這裏注意 =~只能用 ` `去匹配,並且=~後面的PATTERN(模式)不能使用"",''等引用字符

-n -z

-z 測試文件內容是否爲空,爲空時真,不爲空爲假

-n 測試文件內容是否爲不空,不空爲真,空爲假

單目運算符

[ -n "$file_name" ]

文件測試

-a|e -f -L|h -d

-b -c -S -p -s

-r -w -x -N

-a|e 測試文件存在

-f 測試文件爲通常文件

-L|h 測試文件爲軟鏈接文件

-d 測試文件是否爲目錄

-b -c -p -S 測試文件爲塊設備、字符設備、管道文件、socket文件

-r -w -x 測試文件可讀、可寫、可執行

-s 測試文件爲空文件

-N 測試文件Mtime新於Atime

都是單目運算符

[ -f "$file_name" ]

[[ -b "$file_name" ]]

test -x $file_name

-nt -ot

file1 -nt file2 file1的Mtime新於file2的Mtime 

file1 -ot file2 file1的Mtime舊於file2的Mtime 

雙目運算符

[ file1 -nt "$file_name" ]

[[ $file1 -ot "$file_name" ]]


2、邏輯運算

    布爾運算:布爾運算的結果只有2中:真和假。

    常見的邏輯運算有:與 或 非 異或。與或很是用 && || ! 來表示。

    與的邏輯關係:

假 && 任意
真 && 真

     或的邏輯關係:

真 || 任意
假 || 假

    非的邏輯關係:


!假
!真

    異或的邏輯關係:相同爲假,不一樣爲真


3、選擇

    bash中的選擇語句一般有if,case。固然if,case在大多數狀況下是能夠相互轉換的。

1)if選擇語句

一、單分支if語句:

    if CONDITION;then

選擇分支

    fi

二、雙分支的if語句:

    if CONDITION;then

選擇分支1

    else

選擇分支2

    fi

三、多分支的if語句:

    if CONDITION1;then

選擇分支1

    elif CONDITION2;then

選擇分支2

    elif CONDITION3;then

選擇分支3

    ...

    else

選擇分支n

    fi

2)case語句

    語法格式:

        case 變量引用 in

        PATTERN1)

            分支1

            ;;

        PATTERN2)

            分支2

            ;;

        ...

        *)

        分支n

        ;;

        esac

    PATTERN:類同於文件名通配機制,但支持使用「|」表示或者

    a|b: a或者b

    *:匹配任意長度的任意字符

    ?: 匹配任意單個字符

    []: 指定範圍內的任意單個字符


四、練習

寫一個腳本,完成以下任務,其使用形式以下所示:

    script.sh {start|stop|restart|status}

其中:

    若是參數爲空,則顯示幫助信息,並退出腳本;

    若是參數爲start,則建立空文件/var/lock/subsys/script,並顯示「starting script successfully.」

    若是參數爲stop,則刪除文件/var/lock/subsys/script,並顯示「Stop script successfully.」

    若是參數爲restart,則刪除文件/var/locksubsys/script並從新建立,然後顯示「Restarting script successfully.」

    若是參數爲status,那麼:

    若是文件/var/lock/subsys/script存在,則顯示「Script is running...」,不然,則顯示「Script is stopped.」

    說明:script.sh是腳本文件名,在建立時,其名稱能夠本身隨意定義,但若是其名稱發生變量,上/var/lock/sussys/下的文件名也要隨之而變;

[root@server scripts]# cat myhttpd
#!/bin/bash
#
# Description: 
# Version: 0.0.1
# Author: Alex
# Date: 2014-07-09

#判斷參數個數,若是參數小於1,則提示用法並退出
if [ $# -lt 1 ];then
        echo "Usage: `basename $0` {start|stop|restart|status}"
        exit 2
fi
#判斷/var/lock/subsys是否存在,不存在則建立此目錄
if [ ! -d /var/lock/subsys ];then
	/bin/mkdir -p /var/lock/subsys
fi

if [ "$1" == "start" ];then
#若是/var/lock/subsys/`basename $0`文件不存在,則建立,並顯示啓動成功;若存在則提示已啓動
	[ !  -e "/var/lock/subsys/`basename $0`" ] && /bin/touch  "/var/lock/subsys/`basename $0`" && echo "Starting `basename $0` successfully." \
	||  echo "`basename $0` is already start."
elif [ "$1" == "stop" ];then
#若是/var/lock/subsys/`basename $0`文件存在,則刪除,並顯示關閉成功;若不存在則顯示關閉失敗
	[ -e "/var/lock/subsys/`basename $0`" ] && /bin/rm -f  "/var/lock/subsys/`basename $0`" && echo  "Stop myhttpd successfully." \
	|| echo -e "Stopping myhttpd \033[31mFAILED\033[0m."
elif [ "$1" == "status" ];then
#若是/var/lock/subsys/`basename $0`文件存在,顯示running;若不存在則提示stopd
	[ -e "/var/lock/subsys/`basename $0`" ] && echo "`basename $0` is running..." || echo "`basename $0` is stopped."
else
	echo "Usage: `basename $0` {start|stop|restart|status}"
fi

    上面的腳本也能夠用case語句結合函數來實現。

# 通常狀況下,case與函數一塊兒使用的居多。

#!/bin/bash

if [ $# -lt 1 ];then
        echo "Usage: `basename $0` {start|stop|restart|status}"
        exit 2
fi

[ $UID -ne 0 ] && echo "permission denied." && exit 5

if [ ! -d /var/lock/subsys ];then
	/bin/mkdir -p /var/lock/subsys
fi

service_name=`basename $0`
ser_path="/var/lock/subsys/$service_name"
start() {
	if [ !  -e "$ser_path" ];then
 		/bin/touch  "$ser_path" 
		echo "Starting $service_name successfully."
	else 
		echo "$service_name is already start."
	fi 
}

stop() {
	if [ -e "$ser_path" ];then
		/bin/rm -f  "$ser_path"
		echo  "Stop $service_name successfully."
	else
		echo -e "Stopping $service_name \033[31mFAILED\033[0m."
	fi
}

status() {
	if [ -e "$ser_path" ];then
		echo "$service_name is running..."
	else
		echo "$service_name is stopped."
	fi
}

other() {
	echo "Usage: $service_name {start|stop|restart|status}"
	exit 4
}

case "$1" in
  start)
	start
	;;
  stop)
	stop
	;;
  status)
	status
	;;
  *)
	other
	;;
esac


4、其餘

一、組合條件測試:在多個條件間實現邏輯運算

    與:[ condition1 -a condition2 ]

    condition1 && condition2

    或:[ condition1 -o condition2 ]

    condition1 || condition2

    非:[ -not condition ]

    ! condition

二、bash編程之交互編程

    read 與用戶交互進行 

        -p "prompt" 提示語句

        -t timeout 設置超時時間

三、exit

    程序退出語句,通常是 exit n 這樣使用,n是錯誤狀態值。

四、shift

    一般是shift n 這樣使用,n是要踢掉的參數個數

[root@server scripts]# cat ./aboutshift 
#!/bin/bash

echo $1
shift 2 #踢掉2個參數
echo $1
shift 3 #踢掉3個參數
echo $1
[root@server scripts]# ./aboutshift 1 2 3 4 5 6 7 8 9 10
1
3
6

    而shift真正的做用是,判斷腳本參數的問題。例如:

寫一個腳本,使用形式以下所示

    showifinfo.sh [-i INTERFACE|-a] [-v]

要求:

    一、-i或-a不可同時使用,-i用於指定特定網卡接口,-a用於指定全部接口;

        顯示接口的ip地址

    二、使用-v,則表示顯示詳細信息

        顯示接口的ip地址、子網掩碼、廣播地址;

    三、默認表示僅使用-a選項;

#!/bin/bash
#
# 經過這種方法來判斷一個腳本的參數選項

verbose=0
allInterface=0
ifflag=0

while [ $# -ge 1 ]; do
    case $1 in
    -a)
	allInterface=1
        shift 1
	;;
     -i)
	ifflag=1
	interface="$2"
 	shift 2
	;;
     -v)
	verbose=1
	shift
	;;
     *)
	echo "wrong option"
	exit 2
	;;
     esac
done

[ $ifflag -eq 1 -a $allInterface -eq 1 ] && "Usage Error." && exit 12
    
if [ $allInterface -eq 1 || $# -eq 0 ]; then
    if [ $verbose -eq 1 ]; then
	ifconfig | grep "inet addr:"
    else
	ifconfig | grep "inet addr:" | awk '{print $2}' 
    fi
fi

if [ $ifflag -eq 1 ]; then
    if [ $verbose -eq 1 ]; then
	ifconfig $interface | grep "inet addr:"
    else
	ifconfig $interface | grep "inet addr:" | awk '{print $2}' 
    fi
fi		
相關文章
相關標籤/搜索