bash編程之條件判斷:判定後續操作的前提條件是否滿足。
條件判斷的常用測試類型:
1整數測試:比較數值大小,然後判定是否符合條件
2字符測試:比較字符串(是否一樣,字符串大小,是否爲空),然後判定是否符合條件
3文件測試:判斷文件是否存在,文件是否爲目錄,文件是什麼類型
布爾值:
真,假
邏輯運算:
與運算:有假結果爲假
真 && 真 = 真
真 && 假 = 假
假 && 真 = 假
假 && 假 = 假
或運算:有真結果爲真
真 || 真 = 真
真 || 假 = 真
假 || 真 = 真
假 || 假 = 假
非運算:取反運算
! 真 = 假
! 假 = 真
bash中條件判斷使用if:會根據條件進行判斷結果爲真或爲假
單分支:
if 條件; then #如果條件滿足執行分支1;不滿足就退出
分支1;
fi
雙分支:#如果條件滿足執行分支1,不滿足就執行分支2
if 條件; then
分支1;
else
分支2;
fi
多分支:如果條件1滿足執行分支1,如果條件2執行分支2,如果條件3滿足執行分支3,
if 條件1; then
分支1;
elif 條件2; then
分支2;
elif 條件3; then
分支3;
...
else
分支n;
fi
bash中如何做測試:
test:比較表達式, 測試運算.任何命令的執行結果也可以做測試對於命令狀態返回值0爲真,其餘都爲假
格式有三種:test EXPRESSION
[ EXPRESSION ]兩端有必須空格 一個括號和test命令一樣,
` EXPRESSION `兩個括號表示關鍵字
條件測試:
只要命令用作條件,就表示引用是其狀態結果(即執行成功與否),而非命令的輸出結果,因此,不能使用命令替換符``
練習:讓用指定一個文件,判定:
如果文件有空白行,就顯示空白行數;
#!/bin/bash
#
read -p "Enter a file path: " fileName ##讓用戶輸入一個文件賦值給fileName變量,實驗開始的時候加了$符號一直執行不了腳本,一直沒找到原因,READ命令是複製給變量,加了$就變成引用變量了,所以會一直執行不下去
if grep "^$" $fileName &> /dev/null; then #執行grep查找fileName變量文件中是否有空白行,執行結果丟入位桶,因爲只使用命令的執行狀態返回值,沒有使用命令的執行結果所以不用加``.
linesCount=`grep "^$" $fileName | wc -l` #取空白行數的命令結果賦值給變量
echo "$fileName has $linesCount space lines." #
fi
練習:讓用指定一個文件,判定:
如果文件有空白行,就顯示空白行數;否則,就說明文件無空白行;
#!/bin/bash
#
read -p "Enter a file path: " fileName #提示用戶輸入文件路徑,並賦值給fileName
if grep "^$" $fileName &> /dev/null; then #用grep判斷變量fileName文件中是否有空白行,如果有就執行下面語句1
linesCount=`grep "^$" $fileName | wc -l` #用wc -l命令讀取grep命令判斷fileName中有多少空白行
echo "$fileName has $linesCount space lines."
else #如果if處命令返回值爲假則執行語句2
echo "$fileName hava no space line."
fi
bash編程之:整數測試
二元測試:比較兩個數
num1 OPRAND num2
OPRAND比較操作符
-gt: 大於[ $num1 -gt $num2 ]第一個大於第二個數爲真,否則爲假
-lt: 小於
-ge:大於等於
-le: 小於等於
-ne: 不等於
-eq: 等於
練習:判定兩個數孰大孰小,整數是通過命令行參數傳遞而來。
條件判斷中[]號一定要加空格,中括號表示執行判斷要加空格
#!/bin/bash
#
if [ $# -lt 2 ];then #如果腳本參數的個數$#少於2個則提示用戶
echo "stupid..."
echo "`basename $0` argu1 argu2" #用basename取腳本本身$0的基名(顯示腳本文件名),提示用戶提供2個參數
exit 4 #給定執行狀態返回值
fi
if [ $1 -gt $2 ]; then
echo "The max num is $1."
else
echo "The max num is $2."
fi
exit 6
bash知識點:只要命令用作條件,就表示引用是其狀態結果(即執行成功與否),而非命令的輸出結果,因此,不能使用命令替換符;
bash知識點之腳本自定義退出:
腳本狀態返回值:腳本執行的最後一條命令的狀態返回值,所以需要自定義腳本返回值exit n:n爲一個數字,
引用命令的執行結果:使用`COMMAND`或$(COMMAND)
引用命令執行成功與否的狀態結果:一定是直接執行命令,此時,通常需要將執行結果重定向至/dev/null;
if id $userName &> /dev/null #取命令返回狀態.if會根據狀態返回值判斷.
if [ `id -u $userName` -eq 0 ] #取命令執行結果執行成功爲真,失敗爲假!
練習1:寫一腳本,實現如下功能:
1、讓用戶通過鍵盤輸入一個用戶名
2、如果用戶存在,就顯示其用戶名和UID;
3、否則,就顯示用戶不存在;
判斷用戶是否存在
grep "^root\>" /etc/passwd
id root
練習2:寫一腳本,實現如下功能:
1、讓用戶通過鍵盤輸入一個用戶名,如果用戶不存在就退出;
2、如果用戶的UID大於等於500,就說明它是普通用戶;
3、否則,就說明這是管理員或系統用戶;
練習3:寫一腳本,實現如下功能:
1、讓用戶通過鍵盤輸入一個用戶名,如果用戶不存在就退出;
2、如果其UID等於其GID,就說它是個"good guy"
3、否則,就說它是個“bad guy”;
答案1:
答案2:
答案3:
擴展:判斷當前系統上的所有用戶是Good guy還是Bad guy.
bash的知識點:
組合條件測試:對條件做邏輯運算,
&&和||被稱爲短路條件符
與:條件1 && 條件2 如果條件1滿足則執行條件2
條件1爲假,則最終結果一定爲假,因此,條件2將不執行;
條件1爲真,則最終結果決於後麪條件,因此,條件2必須執行;
或:條件1 || 條件2 如果條件1不滿足則執行條件2
條件1爲真,則最終結果一定爲真,因此,條件2將不再執行;
條件1爲假,則最終結果決於後麪條件,因此,條件2必須執行;
非: ! 條件 條件失敗了則執行後面的語句!
#userName=root
#id $userName && echo "$userName exist" #先執行id命令,如果id $userName 執行失敗,就不執行&&後面的echo命令,最終結果就是失敗;如果id命令執行成功,則最終結果取決於echo命令執行的成功與否.echo必須執行
#id $userName && echo "$userName exist" || echo "$userName exist" #如果條件1滿足則執行條件2,如果條件1不滿足,則執行條件3
bash編程之:字符測試:判斷某個字符串能否被模式匹配到,變量儘量加""號,以免報錯
雙目:對字符串進行排序判斷
>: 大於
<: 小於
==: 等於,等值比較
!=, <>:不等於
=~:左側是字符串,右側是一個模式,判定左側的字符串能否被右側的模式所匹配;通常只在[[]]中使用;
模式中可以使用行首、行尾錨定符;但模式中不要加引號;
#[[ "stringA"=~ ot ]]
#userName=root
#[[ `grep "^$userName\>" /etc/passwd |cut -d: -f7` =~ sh$ ]]
#echo $?
單目:判斷一個字符串是否爲空
-n $stringVar: 字符串是否不空,不空爲真,空則爲假;
-z $stringVar: 字符串是否爲空,空則爲真,不空則假;
bash知識點:文件測試
[]
[[]]
test
單目測試:
-e file: 測試文件是否存在;
-a file: 測試文件是否存在;
-f /path/to/file: 測試是否爲普通文件;是爲真,否則爲假
-d /path/to/somefile: 測試是否爲目錄文件;
-b /path/to/somefile: 測試文件是否存在並且是否是一個塊設備文件;
-c /path/to/somefile: 測試文件是否存在並且是否是一個字符設備文件;
-h|-L /path/to/somefile: 測試文件是否存在並且爲符號鏈接文件:
-p /path/to/somefile: 測試文件是否存在並且爲管道文件;
-S /path/to/somefile: 測試文件是否存在並且爲套接字文件;
-r /path/to/somefile: 測試其有效用戶(當前用戶)是否對此文件有讀取權限;
-w 測試其有效用戶(當前用戶)是否對此文件有寫權限
-x 測試其有效用戶(當前用戶)是否對此文件有執行權限
-s /path/to/somefile: 測試文件是否存在並且不空,
雙目測試:
file1 -nt file2: 測試file1是否爲file2更 新一些;file1存在,file2不存在,file1更新
file1 -ot file2: 測試file1是否爲file2更 老一些;
file1 -ef file2: 測試file1是否爲file2引用的同一個設備;
bash的知識點:位置參數輪替(shift)
寫一個腳本:使用形式如下
userinfo.sh -u username [-v {1|2}]
-u選項用於指定用戶;而後腳本顯示用戶的UID和GID;
如果同時使用了-v選項:
-v後面的值如果是1, 則額外顯示用戶的家目錄路徑;
-v後面的值如果是2, 則額外顯示用戶的家目錄路徑和shell;
#!/bin/bash
#
[ $# -lt 2 ] && echo "Too less argements, quit" && exit 3
##首先測試腳本文件參數是否小於2,&&如果小於2提示參數不夠,&&退出碼3
if [[ "$1" == "-u" ]];then userName="$2"
shift 2
fi
##如果參數1字符測試爲"-u" ,參數2就複製給useName變量,執行成功就去掉前兩個參數
if [ $# -ge 2 ] && [ "$1" == "-v" ]; then
verFlag=$2
fi
##如果剩下的腳本參數等2個, 並且剩下的腳本參數1字符測試爲"-v" ,就將參數2賦值給變量"verFlag"
verFlag=${verFlag:-0}
##給變量verFlag默認值爲0
if [ -n $verFlag ];then
if ! [[ $verFlag =~ [012] ]];then
echo "Wrong parameter."
echo "Usage: `basename $0` -u UserName -v {1|2}"
exit 4
fi
fi
##判斷變量verFlag不爲空,結果爲真;執行取反判斷變量verFlag的值不是"012"中的一個,結果爲真;顯示錯誤提示信息,並提示文件參數的輸入格式
if [ $verFlag -eq 1 ]; then
grep "^$userName" /etc/passwd | cut -d: -f1,3,4,6
elif [ $verFlag -eq 2 ];then
grep "^$userName" /etc/passwd | cut -d: -f1,3,4,6,7
else
grep "^$userName" /etc/passwd | cut -d: -f1,3,4
fi
##執行判斷變量verFlag爲1,顯示用戶的家用戶名,UID,GID,目錄路徑;
##執行判斷變量verFlag爲2, 則顯示用戶的家用戶名,UID,GID,目錄路徑和shell
##否則就顯示用戶名,UID,GID
照例在最後放一些習題以供複習:
判定所有用戶是否擁有可登錄shell
練習4:寫一個腳本,實現如下功能:
1、添加10個用戶stu1-stu10;但要先判斷用戶是否存在;
2、如果存在,就用紅色顯示其已經存在
3、否則,就添加此用戶;並綠色顯示;
4、最後顯示一共添加了幾個用戶;
寫一個腳本
1、讓用戶交互式輸入一個用戶名,先判定用戶是否存在;不存在,則以7爲退出碼;
2、判斷用戶的shell是否爲/bin/bash;如果是,則顯示爲“Bash User.”,退出碼爲0; 否則,則顯示爲“Not Bash User.”,退出碼爲1;
寫一個腳本
1、顯示如下菜單:
cpu) show cpu info;
mem) show memory info;
quit) quit
Enter your option:
2、如果用戶選擇cpu,則顯示文件/proc/cpuinfo的信息;
3、如果用戶選擇mem,則顯示文件/proc/meminfo的信息;
4、如果用戶選擇quit,則退出,且退出碼爲5;
5、如果用戶鍵入其它字符,則顯示未知選項,請重新執行腳本;退出碼爲6;
寫一個腳本,完成如下任務:
1、分別複製/var/log下的文件至/tmp/logs/目錄中;
2、複製目錄時,才使用cp -r
3、複製文件時,使用cp
4、複製鏈接文件,使用cp -d
5、餘下的類型,使用cp -a
寫一個腳本,完成如下任務,其使用形式如下所示:
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.”