與其他程式語言相比,bash 當然有提供的流程控制的能力,分別是 if/else、for、case、select、while/until,以下分別介紹這些語法的使用方式。
if/elseif/else 的語法如下:
if condition
then
  statements
[elif condition
  then statements...]
[else
statements]
fi
Exit Status與其他程式語言(C、C++、Pascal....等等)不同的地方,在 
condition 的部分,其他的程式語言是以 condition 為 True or False 來決定要執行哪一段程式;但在 bash 中卻不是如此!
在 bash 中,就必須按照 Linux 的運作方式來進行處理,因此 condition 是否成立取決於 command 的 
exit status。
而在 Linux 的所有指令,不論是由何種程式語言開發,執行完後都會回傳一個整數值給呼叫此程式的 process,此整數值即稱為 exit status;一般來說,「
0」代表程式執行成功,而「
1~255」則代表程式執行失敗。
有了 exit status 的概念後,if/else 的語法就可以修改如下:
if command ran successfully
then
 normal processing
else
 error processing
fi
Return這邊要探討的是一般程式語言都有提供的 
return 功能,其實說穿了,return N 即是 exit N(Exit Status 為N),不過比較不一樣的是,return 僅能用於 function 中,且要執行含有 function 的 shell script,必須透過 source 的方式來執行才有效。
總而言之,在 function 中使用 return 就跟在其他程式語言的方式差不多。
同時使用多個 Exit Status 或許有人會覺得,如果條件判斷中需要同時判斷兩個條件以上,要如何作呢? 在 bash 中當然也辦的到,就像其他程式語言一樣,bash 也可以針對判斷條件進行 
&&(AND) 或是 
||(OR) 運算,來決定是否執行特定程式,以下用個簡單的範例說明:
filename=$1
word1=$2
word2=$3
if grep $word1 $filename || grep $word2 $filename
then
  echo "$word1 or $word2 is in $filename."
fi
各種狀況的判斷當然除了靠 Exit Status 外,還有許多不同的情況會發生,例如:字串比對、檔案屬性的檢查、數字比較....等等,以下逐一來進行介紹各種比對方式。
字串的比對:Operator
  | 成立條件
  | 
str1 = str2
  | 這不多解釋了....
  | 
str1 != str2
  | 這不多解釋了.... | 
str1 < str2
  | 這不多解釋了.... | 
str1 > str2
  | 這不多解釋了.... | 
-n str1
  | 當 str1 不為 null 時
  | 
-z str1
  | 當 str1 為 null 時(長度為 0)
  | 
 檔案屬性:Operator
  | 成立條件
  | 
-a file
  | 檔案存在
  | 
-d file
  | 檔案存在,並且是個目錄
  | 
-e file
  | 檔案存在
  | 
-f file
  | 檔案存在,且為一般檔案(非目錄或其他特殊型態)
  | 
-r file
  | 目前的使用者有讀取檔案的權限
  | 
-s file
  | 檔案存在且內容非空白
  | 
-w file
  | 目前的使用者有寫入檔案的權限 | 
-x file
  | 目前的使用者有執行檔案(or 進入目錄)的權限 | 
-N file
  | 檔案自從上一次被讀取後,有被修改過
  | 
-O file
  | 檔案的 owner 為目前的使用者
  | 
-G file
  | 檔案的 group 為目前使用者所屬之 group
  | 
file1 -nt file2
  | file1 比 file2 的日期新
  | 
file1 -ot file2
  | file1 比 file2 的日期舊
  | 
如果使用上面的判斷時,最好加上「
中括號」,變成類似以下的格式:
if [ condition ] && [ condition ]; then
當然也可以跟 Exit Status 結合,就會變成類似以下的格式:
if command && [ condition ]; then
以下來段簡單的程式(節錄自書):
# 檢查檔案是否不存在
if [ ! -e "$1" ]; then
  echo "file $1 does not exist."
  exit 1
fi
# 檢查是否為目錄
if [ -d "$1" ]; then
  echo -n "$1 is a directory that you may "
  if [ ! -x "$1" ]; then
      echo -n "not "
  fi
  echo "search."
elif [ -f "$1" ]; then  # 檢查是否為檔案
    echo "$1 is a regular file."
else    # 檢查是否為特殊型態的檔案
    echo "$1 is a special type of file."
fi
# 檢查目前使用者是否為 owner
if [ -O "$1" ]; then
  echo 'you own the file.'
else
  echo 'you do not own the file.'
fi
# 檢查是否有讀取檔案的權限
if [ -r "$1" ]; then
  echo 'you have read permission on the file.'
fi
# 檢查是否有寫入檔案的權限
if [ -w "$1" ]; then
  echo 'you have write permission on the file.'
fi
# 檢查第一個參數是否有執行的權限,且非目錄
if [ -x "$1" -a ! -d "$1" ]; then
  echo 'you have execute permission on the file.'
fi
當然,兩兩比較一定會有數字的比對,以下介紹數字比較的方式:
Keyword
  | 效果
  | 
-lt
  | Less than (小於)
  | 
-le
  | Less then or equal (小於或等於)
  | 
-eq
  | Equal (等於)
  | 
-ge
  | Greater than or equal (大於或等於)
  | 
-gt
  | Greater than (大於)
  | 
-ne
  | Not equal (不等於)
  | 
 forfor loop 在 bash 中當然也是不可欠缺的一員大將啦! 只是跟其他程式語言不同的地方,他並非以「
數字」的方式直接指定 for loop 的程式要執行的次數,而是以一個串列的值(例如:1 3 4 6 8)去執行,有幾個值就執行幾次,因此格式大概如下:
for name  [in list ]
do
  statements that can use  $name...
done
其實說穿了,使用方式就跟其他程式語言中的 for each 是差不多相同的,以下結合 if/else 判斷來個範例程式:
#!/bin/bash
IFS=":"
for dir in $PATH
do
  if [ -z "$dir" ]; then
      dir="."
  fi
  if ! [ -e "$dir" ]; then
      echo "${dir} doesn't exist"
  elif ! [ -d "${dir}" ]; then
      echo "${dir} diesn't a directory"
  else
      ls -ld $dir
  fi
done
另外再舉個例子,將 function、for、if/else 通通結合進來,下面這個程式的目的是以 recursive 的方式將參數中目錄底下的所有目錄列出,以下是程式內容:
echoDir() {
  chrTab="${chrTab}t"
  cd $1
  for eachFilePath in $(ls)
  do
      if [ -d $eachFilePath ]; then
          echo -e ${chrTab}${eachFilePath}      
          echoDir $eachFilePath
      fi
  done
  cd ..
  chrTab=${chrTab%'t'}
}
filePath=$1
chrTab=""
if [ -d $1 ]; then
  cd $1
  for eachFilePath in $(ls)
  do
      if [ -d $eachFilePath ]; then
          echo $eachFilePath
          echoDir $eachFilePath
      fi
  done
  cd ..
fi
有興趣知道輸出結果的,可以 copy 回去自己試試看。
casecase 在 bash 中的用法其實就是跟 C、Java 等程式語言中的 switch case 差不多,以下是使用語法:
case expression  in
  pattern1  )
      statements ;;
  pattern2  )
      statements ;;
  ...
esac
以下用個簡單程式來說明:
for filename in "$@"; do
  case $filename in
      *.jpg | *.png ) echo "may be jpg or png" ;;
      *.tga ) echo "tga" ;;
      *.xpm ) echo "xpm" ;;
      * ) echo "can not identified file type."
  esac
done
select這個部分就跟一般的程式語言很不一樣了! 而且僅在 bash 1.14 版以後才有支援喔! 透過 select,可以很容易的產生出選單,以下是使用 select 的語法:
select name  [in  list ]
do
  statements that can use  $name...
done
透過 select 語法,可以將 list 中的內容變成一個個的數字選項供使用者選擇,並且有兩個變數需要注意到,分別是 
$name 以及 
$REPLY;其中 
$name 變數的值為選項的內容,而 
$REPLY 的值則是選項所代表的數字。
當使用者輸入某選項的數字時,$name 與 $REPLY 就會存入相對應的值,但若是輸入一個非選項內的數字,則兩個變數的值都會變成 null,因此可以透過檢查 $name 變數值是否為 null 來判斷使用者有無輸入合法的選項。
以下用一個簡單的小程式來作範例:
#!/bin/bash
# 指定分隔 $PATH 的字元
IFS=":"
#  變數 PS3 儲存使用 select 時提示使用者的字串
PS3="which path you want to use? "
select mySelect in $PATH;
do
  if [ $mySelect ]; then
      echo "mySelect = ${mySelect}"
      echo "REPLY = ${REPLY}"
  else
      echo "no such option!"
      # 透過關鍵字「break」就可離開了!
        break;
  fi
done
# 以下是執行結果:
1) /usr/kerberos/sbin  4) /usr/local/bin      7) /usr/sbin
2) /usr/kerberos/bin   5) /sbin               8) /usr/bin
3) /usr/local/sbin     6) /bin                9) /root/bin
which path you want to use? 1
mySelect = /usr/kerberos/sbin
REPLY = 1
which path you want to use? 5
mySelect = /sbin
REPLY = 5
which path you want to use? 10
no such option!
至於 select 要如何應用在許許多多的管理工作上,就需要管理者發揮創意了!
while & until在 while 與 until 的部分,也是跟一般程式語言中的用法差不多,以下分別介紹 while 與 until 的語法:
whilewhile condition do
  statements... done
untiluntil command ; do       statements... done 
其實說穿了,while 與 until 不過就是一體兩面的用法而已,差別僅在於 while 判斷條件是否為 
true,until 判斷條件是否為 
false。
以下用兩段程式來說明,以下兩段程式的作用是相同的,只是分別以 while 與 until 來撰寫:
until [ cp $1 $2 ];
do
  echo 'Attempt to cpoy failed. waiting...'
  sleep 5
done
while [ ! cp $1 $2 ];
do
  echo 'Attempt to cpoy failed. waiting...'
  sleep 5
done
這裡僅是簡單用法的介紹,其他就靠大家發揮了!