Shell結構化命令:控制流(上)

if - then - else語句

if - then - else語句類似我們常用的if - else,基本格式:

if command 
then
commands
else
commands
fi

不同於if - else的是:if - else判斷條件是否成立依賴truefalse,而if - then語句依賴於ifshell command是否成功執行,即:命令的退出狀態碼是0

若是0,則then後的命令被執行;若不是0,則else後的命令被執行。fi表示if - then - else語句到此結束。

if - then - else語句也可以像if - else語句一樣嵌套使用,基本格式:

if command1 
then
command set 1 
elif command2
then
command set 2 
elif command3 
then
command set 3 
elif command4 
then
command set 4
fi

test命令

如果需要if - then - else語句,判斷退出狀態碼之外的條件,如:truefalse,怎麼辦?解決辦法,使用test命令:test condition

test命令的描述:

test用於評估表達式,如果它評估結果爲true,則會返回退出狀態碼:0true);否則,返回退出狀態碼:1false);如果沒有表達式,test命令也會返回退出狀態碼:1false)。

testif - then - else配合:

if test command 
then
commands
else
commands
fi

test的同義命令,方括號:[ ]

基本使用格式:

if [ condition ] then
commands
fi

注意:第一個方括號之後和第二個方括號之前必須加上一個空格, 否則就會報錯。

布爾邏輯支持:

[ condition1 ] && [ condition2 ] #與運算
[ condition1 ] || [ condition2 ] #或運算

test支持的判斷:

  1. 數值比較
數值比較 描述
n1 -eq n2 檢查n1與n2是否相等
n1 -gen2 檢查n1是否大於等於n2
n1 -le n2 檢查n1是否小於等於n2
n1 -gt n2 檢查n1是否大於n2
n1 -lt n2 檢查n1是否小於n2
n1 -ne n2 檢查n1是否不等於n2
#! /bin/bash
# 控制流
var1=133
var2=145

if [ $var1 -eq $var2 ] 
then
  echo "$var1 等於 $var2"
elif [ $var1 -ge $var2 ]
then
  echo "$var1 大於等於 $var2"
elif [ $var1 -le $var2 ]
then
  echo "$var1 小於等於 $var2" #腳本輸出:133 小於等於 145
elif [ $var1 -lt $var2 ]
then
  echo "$var1 小於 $var2"
elif [ $var1 -gt $var2 ]
then
  echo "$var1 大於 $var2"
elif [ $var1 -ne $var2 ]
then
  echo "$var1 不等於 $var2"
else
  echo "不識別"
fi

exit 0

注意,在test命令中使用浮點數會報錯:145.5: integer expression expectedbash shell只能處理整數。

  1. 字符串比較
字符串比較 描述
str1 = str2 檢查str1和str2是否相等
str1 != str2 檢查str1和str2是否不相等
str1 > str2 檢查str1是否大於str2
str1 < str2 檢查str1是否小於str2
-n str1 檢查str1的長度是否非0
-z str1 檢查str1的長度是否爲0
#! /bin/bash
# 字符串比較
var1="abc"
var2="acb"
var3=""
var4="abc"

if [ -n $var1 ];then
 echo "字符串var1的長度大於0" #執行腳本輸出
fi

if [ $var2 ];then
 echo "字符串var2有值"#執行腳本輸出
fi

if [ -z $var3 ];then
 echo "字符串var3的長度爲0"#執行腳本輸出,var3未初始化也會執行
fi

if test $var4 = $var1 ; then
  echo "字符串var4=var1"#執行腳本輸出
  if [ $var1 \> $var2 ]; then
   echo "字符串var1 > var2"#執行腳本輸出
  elif [ $var1 != $var2 ]
  then
   echo "字符串var1不等於var2"
  else 
   echo "字符串var1小於var2"
  fi
else
  echo "字符串var4!=var1"
fi

exit 0

注意: 大於號和小於號必須轉義,否則shell會把它們當作重定向符號,把字符串值當作文件名;大於和小於順序和sort命令所採用的不同。

  1. 文件比較
文件比較 描述
-d file 檢查file是否存在並且是個目錄
-e file 檢查file是否存在
-f file 檢查file是否存在並且是個文件
-r file 檢查file是否存在並且可讀
-w file 檢查file是否存在並且可寫
-x file 檢查file是否存在並且可執行
-s file 檢查file是否存在並且非空
file1 -nt file2 檢查file1是否比file2新
file1 -ot file2 檢查file1是否比file2舊
-O file 檢查file是否存在並屬當前用戶所有
-G file 檢查file是否存在並且默認組與當前用戶相同

示例:創建一個新的目錄,新的文件,寫入腳本數據,改變文件的權限,並執行該腳本。

#! /bin/bash
#文件比較
var1="./compare"
var2="wonderful"
if [ -d $var1 ]; then
   echo "${var1}目錄存在,"
   if [ -f $var1/$var2 ] && [ -s $var1/$var2 ]
   then
     echo "${var2}文件存在,並且不爲空,切換工作區"
     cd ./${var1}
     if [ -x $var2 ]; then
       echo "文件存在,且可執行,內容如下:"
       cat -n $var2
       ./$var2
     else
       echo "文件存在,不可執行,寫入腳本"
       ( echo "#! /bin/bash" ) > $var2
       ( echo "echo $(date) 執行 $var1/${var2}腳本成功🔥")>>$var2
       echo -n "修改權限並執行結果"
       chmod u+x $var2
       ./$var2
     fi
   else
   echo "${var2}文件不存在或文件爲空"
   cd ./${var1}
      if [ -e $var2 ]; then
          echo "文件存在"
      else
          touch $var2
      fi
   echo "寫入'script'到文件 $var2 "
   ( echo "#! /bin/bash" ) > $var2
   ( echo "echo $(date) 執行 $var1/${var2}腳本成功🔥")>>$var2
   echo "改變 $var2 的權限爲可執行"
   chmod u+x $var2
   echo "執行${var2}腳本"
   ./${var2}

   fi
else
   echo "${var1}目錄不存在"
   echo "創建 $var1 目錄"
   mkdir $var1
   echo "切換目錄"
   cd $var1
   echo "當前工作目錄:$PWD"
   echo "創建空文件:$var2"
   touch $var2
   echo "寫入'script'到文件 $var2 "
   ( echo "#! /bin/bash" ) > $var2
   ( echo "echo $(date) 執行 $var1/${var2}腳本成功🔥")>>$var2
   echo "改變 $var2 的權限爲可執行"
   chmod u+x $var2
   echo "執行${var2}腳本"
   ./${var2}
fi

if - then - else的高級特性

  • 用於數學表達式的雙括號
  • 用於高級字符串處理功能的雙方括號

雙括號

雙括號:允許在比較過程中使用高級數學表達式,而test只支持簡單的算術比較:gtge...。

注意:可以在if語句中用雙括號命令,也可以在腳本中的普通命令裏使用來賦值。

基本格式:

(( expression ))

雙括號支持的高級數學表達式:

符號 描述
val++、++val 後/前增
val--、--val 後/前減
!、&&、||、 邏輯取反、與、或
~、&、|、>>、<< 按位取反、與、或、右移、左移
** 冪運算

示例:

#! /bin/bash
# 控制流
var=5

if (( $var ** 3 > 100 ));then
   echo "雙括號的賦值操作:"
   var1=$var
   (( var = $var ** 3 ))
   echo -n "輸出$var1 ** 3的值爲: $var" #輸出5 ** 3的值爲: 125
   echo ""
fi

雙方括號

雙方括號:該命令針對字符串比較提供的高級特性。
基本格式:

[[ expression ]]

雙方括號裏的expression可使用test命令中採用的標準字符串比較,同時它還使用test命令沒有的特性:模式匹配。
模式匹配使用==,雙等號右邊的字符串會被視爲一個模式。
示例:

#! /bin/bash
# 控制流
if [[ $USER == q* ]]
then
echo "Hello $USER"
else
   echo "匹配失敗"
fi

case命令

case命令採用模式匹配的方式,進行變量的匹配。

case命令的基本格式:

case variable in
pattern1 | pattern2) #豎線操作符在一行中分隔出多個模式
commands1;;
pattern3)
commands2;;#注意必須要雙分號,這是語法的一部分
*) 
default commands;
esac #結束標誌

示例:

#! /bin/bash
# 控制流
case $USER in 
*li|*n*)
echo "hello $USER";;
li)
echo "hi li";;
*)
echo "by";;
esac

參考資料:

Linux命令行與shell腳本編程大全

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章