BASH編程基礎之變量、條件判斷

一、前言

在linux中,通常我們所指的腳本編程,指的是bash的腳本編程。

bash作為一種過程式的編程語言來說,它應該具備編程語言所應該具備的基本元素,即:變量,流程,函數,數組。今天我們介紹變量以及流程之一的條件判斷。

二、變量

1、初識變量

在編程語言中,編程語言有兩大種,強類型語言和弱類型語言。強類型語言中,要求變量的使用要嚴格符合定義,所有變量都必須先定義后使用。java、.NET、C++等都是強制類型定義的。與其相對應的是弱類型語言:數據類型可以被忽略的語言。它與強類型定義語言相反, 一個變量可以賦不同數據類型的值。

常見的數據類型有:
數值型:整形,浮點型,布爾型
字符型:單字符,字符串

bash屬于弱類型語言,其默認的變量類型為字符型。

2、bash中的變量

我們知道,變量可以按其數據的類型進行劃分,在bash中變量按其作用域的不同,也可以進行不同的劃分。

  a) 局部變量:在bash腳本中,其作用域范圍為局部性,比如想限制變量只在某函數中起作用

  b) 本地變量:在bash腳本中,其作用域范圍為整個腳本,即腳本開始到結束

  c) 環境變量:系統工作使用的變量,常見的環境變量有,$PATH, $HOME, $PWD, 等等

  d) 位置參數變量:用于向腳本中傳遞參數

  e) 特殊變量:bash中預先定義好的具有特殊意義的比變量,如:$0, $1, $#, $@,….

3、bash中的變量的定義和使用

  a) 聲明某變量為局部變量:local VAR_NAME=VALUE

  b) 聲明某變量為本地變量:

    I) 不指定類型,默認類型為字符型  : VAR_NAEM=VALUE

    II) 定義數據類型為整數型:let VAR_NAME=VALUE 或 declare -i VAR_NAME=VALUE

    III) 聲明某變量為環境變量:export VAR_NAME=VALUE 或 declare -x VAR_NAME=VALUE

三、第一個腳本

# vim script01.sh

# 編輯如下內容
#!/bin/bash
# Pragram: This is test scirpt.
# Author: FengYuxiu
# Version: 1.0
# History: 2015/06/29

echo "Hello World."

# 保存內容并退出
#
# bash -n script01.sh
# bash -x script01.sh

blob.png

顯示執行過程,并執行成功,顯示echo中的內容。

其中,在bash腳本中有一些規定好的規則
1、第一行為固定格式,#!/bin/bash, 表示這是一個bash的腳本,而不是一個普通的文本文件,讓bash解釋器執行以下語句。

2、# 為注釋行,除了第一行中的#!/bin/bash

3、執行bash腳本的方法有兩種,一個是給腳本加上執行權限,并指明執行路徑,另一個是直接向bash命令傳遞腳本名,讓bash解釋執行腳本的內容

4、bash -n SCRIPT_NAME.sh 檢查腳本的是否存在語法錯誤

5、bash -x SCRIPT_NAME.sh 查看腳本的執行過程,用于腳本排錯

四、腳本的條件測試

說起條件測試,我們就想起布爾型,當然,測試的結果返回值只有兩種,真或者假。其中在bash中0表示真,0以外表示假。

1、整數的測試:(整數A和B)

  A -gt B: A大于B

  A -lt B: A小于B

  A -eq B: A等于B

  A -ge B: A大于等于B

  A -le B: A大于等于B

  A -ne B: A不等于B

2、字符串測試:(字符串A和字符串B)

  A == B 或 A = B: 字符串等值比較

  A !=B : 不等于

  -z A: 判斷A是否為空,空為真,不空為假

  -n A: 判斷A是否為不空,不空為真,空為假

3、條件測試的方法:

  a) test 測試表達式

  b) [ 測試表達式 ] : []與于測試表達式之間必須要有一個半角空格,否則語法錯誤

  c) [[ 測試表達式 ]] : 等同于[ 測試表達式 ], 但有些特殊場合需要用到[[ 測試表達式 ]]

4、條件測試方法在腳本中的使用

if 條件表達式; then
    command1
    command2
    .....
fi

blob.png

當然,if的條件表達式可以嵌套,也可以進行多個條件判斷

if 條件表達式; then
    command1
    command2
    if 條件表達式; then
        command3
        command4
        .....
    fi
elif  條件表達式; then
    command5
    command6
    ....
else
    commandN
fi

blob.png

五、基于if的條件測試腳本

練習1、向腳本中傳遞一個0-100的數字,85以上輸出“A”,大于70小于85的輸出“B”,大于60小于70的輸出“C”,其他的輸出“D”。

#!/bin/bash

# 初始化score的值
declare -i score=0
# 把參數1的值復制給score
score=$1

if [ $score -ge 85 ]; then
    echo "Rank is A."
elif [ $score -ge 70 ]; then
    echo "Rank is B."
elif [ $score -ge 60 ]; then
    echo "Rank is C."
else
    echo "Rank is D."
fi

blob.png

知識點補充:使用$1,$2, $N, 可以獲取腳本的參數,沒有傳遞時,獲取為空值。

  $0表示執行的腳本名

  $#表示腳本參數的個數

  $@表示腳本的腳本的所有參數,數據結構為數組

  $*表示腳本的所有參數,數據結構為字符串

blob.png

練習2、在練習1的基礎上,向腳本傳遞兩個參數,參數1為用戶名,參數2為分數,顯示該學生所對應的等級。并且參數最少為2個,且第二個參數必須為數值。

#!/bin/bash

# 判斷向腳本傳遞參數的個數,參數個數小于兩個,返回錯誤并結束腳本。
if [ $# -lt 2 ]; then
    echo "The parameter is less than 2."
    exit 1
fi

# 判斷參數2是否為數值,數值以外,顯示錯誤,并退出腳本。
# 此處對數值沒有進行精確判斷,因此沒有過濾以0開頭的數值
if  ! echo "$2" | grep "[[:digit:]]\{1,\}" &> /dev/null ; then
    echo "Please input like ->> $0 name score" 
    exit 1
fi

declare -i score=0
name=$1
score=$2

if [ $score -ge 85 ]; then
    rank=A
elif [ $score -ge 70 ]; then
    rank=B
elif [ $score -ge 60 ]; then
    rank=C
else
    rank=D
fi

echo "${name}'s score is $rank"

blob.png

練習3、驗證輸入數值的正確性,分數的范圍必須在0-100之間。

#!/bin/bash

declare -i score=0

if [ $# -lt 2 ]; then
    echo "The parameter is less than 2."
    exit 1
fi

if  echo "$2" | grep "[[:digit:]]\{1,\}" &> /dev/null ; then
    if [ $2 -ge 0 -a $2 -le 100 ]; then
        name=$1
        # 在把值復制給score變量前,用sed把前面的0都給去掉
        score=$(echo $2 | sed 's/^0*//')
        if [ $score -ge 85 ]; then
            rank=A
        elif [ $score -ge 70 ]; then
            rank=B
        elif [ $score -ge 60 ]; then
            rank=C
        else
            rank=D
        fi
        
        echo "${name}'s score is $rank"
    else
        echo "Please enter 0 to 100 points."
    fi
else
    echo "Please input like ->> $0 name score" 
    exit 1
fi

blob.png

六、基于case的條件測試腳本

case其實也可以說是簡潔版的多跟支if語句。它的語法格式如下:

case 變量引用 in

PATTERN1)
    分支1
    ;;
PATTERN2)
    分支2
    ;;
    ......
*)
    分支n
    ;;
esca

blob.png

PATTERN表示的是匹配條件,具體格式如下:

  *:表示任意長度字符

  ?:任意單個字符

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

  A|B:A或B

練習1、寫一個腳本,向腳本傳遞一個參數,如cpu,mem,idisk(表示disk info),udisk(表示disk usage),顯示相應參數所對應的信息。

#!/bin/bash

case $1 in
cpu)
    lscpu
    ;;
mem)
    free
    ;;
idisk)
    fdisk -l /dev/sd[a-z]
    ;;
udisk)
    df -h
    ;;
*)
    echo "Usage: $0 {cpu|mem|idisk|udisk}"
    ;;
esac

blob.png

blob.png

blob.png

blob.png

blob.png

七、條件測試知識擴展

1、字符串測試:

  "$A" =~ PATTERN: 如果變量中保存的字符串能被PATTERN匹配,則為真,否則為假

2、文件測試:

  -e $file : 判斷文件是否存在,存在為真

  -f $file: 判斷文件是否存在,且為普通文件,滿足條件為真

  -d $file: 判斷是否存在且為為目錄

  -b $file: 判斷是否存在且為塊設備

  -c $file: 判斷是否存在且為字符設備

  -S $file: 判斷是否存在且為套接字設備

  -p $file: 判斷是否存在且為管道設備

  -L $file: 判斷是否存在且為符號鏈接文件

  -r,w,x $file: 判斷用戶是否對此文件有讀,寫,執行權限

  -u,g,k $file: 判斷文件是否擁有suid,sgid, sticky的權限

  -O,-G $file: 判斷當前用戶是否為此文件的屬主,屬組

  $file1 -nt $file2: (new than) 判斷文件1是否比文件2新

  $file1 -ot $file2: (old than) 判斷文件1是否比文件2新

  $file1 -et $file2:  判斷文件1是和文件是否為同一個文件的硬鏈接

blob.png

八、條件判斷腳本的實戰練習

功能:向腳本傳遞兩個參數,第一個為fstab或bash,第2個參數為文件名,然后用vim打開對象文件編輯,并在用戶保存退出文件時,對保存修改后的腳本進行語法檢查。

#!/bin/bash
# Pragram: This is Grammar test script.
# Author: FengYuxiu
# Version: 1.0
# History: 2015/07/04

# 進行參數判斷
if [ $# -lt 2 ]; then
    echo "Please enter an filename."
    exit 1
fi

filename=$2

# 判斷文件是否存在
if [ ! -e $filename ]; then
    echo "file is not exits "
    read -p "Use the $filename to create new file.(yes/no): " yesno
    if [ ${yesno:=no} == "yes" -o $yesno == "y" ]; then
       touch $filename 
    else
       exit 1
   fi
fi

# 判斷文件是否為普通文件
if [ ! -f $filename ]; then
    echo "Please enter ASCII text."
    exit 1
fi

case $1 in
bash|sh)
    vim $filename
    # 對文件進行語法檢查,并把錯誤信息保存到errmsg變量中
    errmsg=$(bash -n $filename 2>&1)
    
    if [ -n "$errmsg" ]; then
        clear
        echo "$errmsg" 
        read -t 15 -p "Syntax error.Whether to modify.(yes/no): " isedit
        if [ ${isedit:no} == "yes" -o $isedit == "y" ]; then
            vim $filename
        fi
    fi
    
    # 因為是腳本,所以加上執行權限
    chmod u+x $filename
    ;;
fstab)
    vim $filename
    # 用mount -a 對掛載文件進行語法檢測
    errmsg=$(mount -a 2>&1) 
    
    if [ -n "$errmsg" ]; then
        clear
        echo "$errmsg"
        read -t 15 -p "Syntax error.Whether to modify.(yes/no): " isedit
        if [ ${isedit:no} == "yes" -o $isedit == "y" ]; then
            vim $filename
        fi
    fi
    ;;
*)
    echo "Usage $0 {bash|sh|fstab} filename."
    exit 1
esac

clear
echo "$filename is save success."

1、執行腳本

blob.png

2、故意使腳本語法錯誤,保存并退出

blob.png

3、提示語法錯誤,并提示是否修改,輸入yes回到vim界面修改,輸入no結束,此處輸入yes返回vim

blob.png

4、修改完成,保存并退出

blob.png

5、顯示成功信息

blob.png

注意:此處的腳本只用到條件判斷語句,沒有用到循環,所以語法判斷只能進行一次。

好了,以上的整理如有遺漏或錯誤,還請大神賜教。

原創文章,作者:封于修,如若轉載,請注明出處:http://www.www58058.com/5977

(1)
封于修封于修
上一篇 2015-07-06 09:19
下一篇 2015-07-06 09:33

相關推薦

  • zabbix報警信息提取

    zabbix報警信息提取     在日常的監控中,我們除了日常的zabbix操作外,我們有的時候還涉及到與其他公司進行數據對接。由于別的公司的數據對接很多時候并不是按照zabbix的數據結構(尤其是大型廠家,或是專業監控廠家,并不會直接使用zabbix,多數是自己開發或是對其他監控軟件進行二次開發之類),在這種需求基礎…

    Linux干貨 2015-12-19
  • 第四周 博客作業

    grep useradd cp

    Linux干貨 2017-12-28
  • 馬哥教育網絡班21期+第一周課程練習

    1,描述計算機的組成及其功能。 2.按系列羅列linux的發行版,并描述不同發行版之間的練習與區別。 3.描述linux的哲學思想,并按照自己的理解對其進行解釋性描述。 1.       一切皆文件,計算機中所有的文件目錄,        包括計算機的硬件設備顯示為文件格式。 2…

    Linux干貨 2016-07-07
  • 跟我一起學man page、history的使用,剖析FHS(文件系統目錄標準)

    跟我一起學man page、history的使用,剖析FHS(文件系統目錄標準) 描述 從Linux小白鼠成長為高(lao)高(hei)手(shu)的過程中,無論如何都要學會自個兒施法解決問題,法力的高深體現了解決問題的能力,這里的法力指的是在沒有互聯網的環境下如何使用man page或相關文檔找到命令的使用方法和配置文件的修改方法。本文第一部分總結了在Li…

    Linux干貨 2016-07-29
  • 01day-計算機與操作系統基礎

    第1章 計算機基礎 1.1 什么是計算機 計算機是個籠統的概念,泛指一切計算功能的機器。這樣扯的話,以前的算盤也是計算機了。我們現在的計算機應該稱作電子計算機,我天朝人民稱為電腦。聽說谷歌在研究量子計算機,完全不懂是什么玩意。 一不小心在百度百科看到還有光子計算機,生物計算機,嚇我一跳,趕緊復制鏈接過來,自己慢慢看《百度百科—-計算機》 &nbs…

    Linux干貨 2016-06-29
  • 馬哥linux運維26期開班感悟

         今天的收獲,有以下幾點      1.自己的公眾演說能力很弱,要多多練習,給自己更多的機會。     2.自己想提升自己的心很強,但是自己卻不知道該怎么做?     3.即便學完了也只是一個開始,希望自己有一顆歸零的心態。

    Linux干貨 2017-07-10
欧美性久久久久