1. 程式人生 > >bash腳本編程之if分支結構和位置變量的應用以及交互示例

bash腳本編程之if分支結構和位置變量的應用以及交互示例

bash腳本編程

bash腳本編程的結構:

bash腳本編程語言是腳本類語言、解釋型語言、過程式編程語言。


過程式編程語言的結構:

順序執行結構(默認):

從上到下,自左而右的執行所有的語句(命令)

選擇執行結構:

當條件滿足或不滿足時,才會執行對於的語句(命令)

循環執行結構:

重復執行某段語句(命令)


在bash腳本編程語言中也具備上述結構:

順序執行結構:bash默認的執行結構


選擇執行結構:

根據給定的條件的邏輯判斷結果或根據某個可選取的取值範圍進而選擇某個分支結構中的語句(命令)予以執行;

if:分支選擇執行結構的標準,根據條件的邏輯判斷結果來選擇執行的語句內容;

case:選擇執行結構的標準,根據符合某特定範圍的取值標準來選擇執行的語句內容;


循環執行結構:對於結構內的特定語句內容,重復執行0次,1次或多次;

for循環:遍歷列表的方式來進行循環;

while循環:根據給定的邏輯判斷結果來進行循環;邏輯判斷結果為真才循環,否則停止循環;

until循環:根據給定的邏輯判斷結果來進行循環;邏輯判斷結果為假才循環,否則停止循環;

select循環:死循環,即沒有默認退出條件的循環;利用循環提供一個可選擇的列表;



bash腳本的執行結構之if選擇執行結構:

if語句:格式:

if: if 命令; then 命令; [ elif 命令; then 命令; ]... [ else 命令; ] fi ---用fi作結尾,與if遙相呼應


if執行結構包括單分支、雙分支以及多分支執行結構:

if語句的單分支結構:

if 命令; then 命令; fi

註意:是否會執行then後面的命令,取決於if後面的命令的執行狀態返回值;

1.如果返回值為真,則執行後面的命令;

2.如果返回值為假,則不執行後面的命令;

書寫形式兩種:

if CONDITION ; then

STATEMENT

...

fi

if CONDITION

then

STATEMENT

...

fi


if語句的雙分支結構:

if 命令; then 命令; elif 命令; fi

註意:是否會執行then或else後面的命令,取決於if後面的命令的執行狀態返回值;

1.如果返回值為真,則執行then後面的命令;

2.如果返回值為假,則執行else後面的命令;

書寫形式兩種:

if CONDITION ; then

STATEMENT

...

else

STATEMENT

...

fi

if CONDITION

then

STATEMENT

...

else

STATEMENT

...

fi


if語句的多分支結構:

if 命令; then 命令; [ elif 命令; then 命令; ]... [ else 命令; ] fi

註意:是否會執行then或else後面的命令,取決於if後面的命令的執行狀態返回值或else後面的命令的狀態返回值;

1.首先判斷if後面的命令的狀態返回值是否是真,如果為真,就執行then後的語句;如果為假,就繼續判斷第一個elif後面的命令的執行狀態返回值;

2.第一個elif後面的命令的執行狀態返回值為真,就執行elif語句中then後面的命令,否則,就繼續判斷第二個elif後面的命令的執行狀態返回值;

3.以此類推,會判斷每個elif後面的命令的執行狀態返回值是否是真;如果使用的if和elif後面的命令的執行狀態返回值均為假,則執行else後面的語句;

書寫格式兩種:

if CONDITION1 ; then

STATEMENT

...

elif CONDITION2 ; then

STATEMENT

...

elif CONDITION3 ; then

STATEMENT

...

...

else

STATEMENT

...

fi

if CONDITION

then

STATEMENT

...

elif CONDITION2 ; then

STATEMENT

...

elif CONDITION3 ; then

STATEMENT

...

...

else

STATEMENT

...

fi


if的多分支結構,用到的不多,有時候可以使用嵌套的單分支或雙分支if結構代替if多分支結構;


嵌套的if結構:

if CONDITION1 ; then

if CONDITION2 ; then

if CONDITION3 ; then

STATEMENT

...

else

STATEMENGT

...

fi

else

STATEMENT

...

fi

else

STATEMENT

...

fi


例:寫一個腳本,判斷某個用戶的的默認登錄shell是否為/bin/bash,如果不是,顯示其登錄shell;


#!/bin/bash

#

USERNAME=$(cut -d: -f1 /etc/shadow | sort -R | head -1)

USERSHELL=$(egrep "^$USERNAME\>"" /etc/passwd | cut -d: -f7)

if [ $"USERSHELL" == "/bin/bash" ] ; then

echo "${USERNAME}'s login is /bin/bash"

else

echo "${USERNAME}'s login is ${USERSHELL}"

fi


//最後要撤銷已經定義過的變量,否則會造成內存空間的浪費

unset USERNAME USERSHELL



bash腳本編程之用戶交互使用:

位置參數變量:

$0:命令的本身,對於腳本而言,就是該腳本的路徑;

$1,$2,...$N:腳本後面通過命令行給腳本傳遞命令行參數;

【N>9時,引用該位置變量時需要加花括號{},即${10}】


特殊變量:

$@:給出的所有位置參數的列表,當使用雙引號引用時,每個參數作為單獨的字符串存在;

$*:給出的所有位置參數的列表,當使用雙引號引用時,整個參數列表被當做一個字符串;

$#:表示除了$0之外傳遞參數的個數;


{shift:shift: shift [n]

移位位置參數。

重命名位置參數 $N+1、$N+2 ... 到 $1、$2 ... 如果沒有給定 N,

則假設為1.

退出狀態:

返回成功,除非 N 為負或者大於 $#。

具體含義:在腳本中添加shift命令後,$0指文件的路徑基名,無法被替換,shift無法對$0進行移位,只能相應的對後面的$1進行移位操作,shift命令操作之後(默認是移動1位),原來的$0保持不變,原來的$1被移位即消除沒有了,原來的$2變成了進行shift命令操作後的$1,原來的$3變成了進行shift命令操作後的$2,後續位置元素同樣道理;當(shift 2)命令操作即移位2位,原來的$3變成了移位操作後的$1}



read命令:

read [-a 數組] [-p 提示符] [-t 超時] [-u 文件描述符] [名稱 ...]

-a array:定義索引數組;

-p prompt:給用戶輸出提示信息;

-t timeout:用戶輸入的超時時間;

name:變量或數組的名稱;如果省略此內容,bash會將read讀到的信息保存到一個內置的名為REPLY變量中


註意:Linux哲學思想之一:盡量不與用戶交互;在使用read時,通常使用-t選項來指定與用戶交互的時間,一旦交互時間超過預定時間,腳本中後續的命令內容會自動被執行;因此,通常需要在後面判斷通過read賦值的變量值是否為空,如果為空,可能需要為該變量提供默認值;

read -t 5 VAR1

[ -z $VAR1 ] && VAR1=value1 --提供默認值



例:

管理用戶的腳本:

腳本可以接受兩個參數,第一個參數為-a或者-d,第二個參數為用戶名;如果第一個參數是-a,則創建其後面參數命名的用戶;如果第一個參數為-d,則刪除其後面參數命名的用戶;

#!/bin/bash

#

if [ $# -ne 2 ];then

echo "Make sure provide TWO argumengts."

exit 5

fi


if [ $1 == '-a' ];then

if ! id $2 &> /dev/null ;then

useradd $2 &> /dev/null

echo $2 | passwd --stdin $2 &> /dev/null

echo "User $2 has created successfully and it's passwd has changed to it's username."

else

if id $2 &> dev/null ;then

echo "User $2 has existed."

fi

fi

elif [ $1 == '-d' ];then

if id $2 &> /dev/null;then

userdel $2 $> /dev/null

echo "User $2 deleted finihed."

else

echo "User $2 does not exists yet."

fi

else

echo "Usage: $(basename $0) -a USERNAME | -d USERNAME"

exit 6

fi



和用戶交互使用read命令:

#!/bin/bash

#

if [ $# -ne 2 ];then

echo "Make sure provide TWO argumengts."

exit 5

fi


if [ $1 == '-a' ];then

read -p "Please input a username for creating: " USERNAME

if ! id $USERNAME &> /dev/null ;then

useradd $USERNAME &> /dev/null

echo $USERNAME | passwd --stdin $USERNAME &> /dev/null

echo "User $USERNAME has created successfully and it's passwd has changed to it's username."

else

if id $USERNAME &> dev/null ;then

echo "User $USERNAME has existed."

fi

fi

elif [ $1 == '-d' ];then

read -p "Please input a username for deleting: " USERNAME

read -p -t5 "Are you sure to delete $USERNAME? Input 'yes/no' to be next." CHOICE

[ -z $CHOICE ] && CHOICE='no'


if [ $CHOICE == 'yes' ];then

if id $USERNAME &> /dev/null;then

userdel $USERNAME $> /dev/null

echo "User $USERNAME deleted finihed."

else

echo "User $USERNAME does not exists yet."

fi

else [ $CHOICE == 'no' ];then

echo "$USERNAME is not deleted."

fi

else

echo "Usage: $(basename $0) {-a | -d}"

exit 6

fi


bash腳本編程之if分支結構和位置變量的應用以及交互示例