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
下一篇 2015-07-06

相關推薦

  • LVM work?。?!

    1、創建一個至少有兩個PV組成的大小為20G的名為testvg的VG;要求PE大小為16MB, 而后在卷組中創建大小為5G的邏輯卷testlv;掛載至/users目錄.     (1)查看分區大小 [root@localhost ~]# lsblk NAME   MAJ…

    Linux干貨 2016-09-01
  • LAMP—Apache編譯安裝

    一、前言:   httpd-2.2與 httpd-2.4版本相比增加了許多新特性:    1、MPM支持運行時裝載    2、支持event    3、支持異步讀寫    4、支持每模塊每目錄使用不同的日志級別    5、每請求配置<IF&gt…

    Linux干貨 2015-06-15
  • 推薦-Linux命令幫助的獲取

    幫助命令 1. 使用幫助命令和幫助選項來獲取幫助 2. 使用man來查看命令使用手冊(manual) 3. 使用info來查看命令的信息頁 4. 程序自身的幫助文檔 5. 程序官方文檔 6. 發行版的官方文檔 7. 使用Google搜索關鍵字 1. 使用幫助命令和幫助選項來獲取幫助 Linux系統中命令分為【內部命令】和【外部命令】。 【內部命令】:內部命令…

    Linux干貨 2016-03-25
  • bash腳本之進階

    bash腳本 1、終端打印 1、單雙引號(echo) 雙引號: ①在雙引號里面打不出! ②雙引號,可以在文本中使用“;”,“;”在bash中被用作命令定界符。 單引號: 變量替換在單引號中無效。 2、printf:不會自動添加換行符,要手動添加 如下: 結果: 3、補充: echo 要使用轉義系列需要加e,!號除外 2、變量和環境變量 腳本語言通常…

    Linux干貨 2016-11-28
  • 一個開發眼中的運維

    在云計算時代,開發和運維的結合變得越來越重要。在DIFF論壇第一期,前新浪SAE運維主管,鄭志勇,分享了《一個開發眼中的運維》根據自己從開發人員轉型運維之后的心得,談如何把在開發上的運用抽象思維方式運用到運維領域。 1. 運維不是什么? 運維不是打雜的,運維不是客服,運維也不是服務開發的,但要做好合作。 2. 運維是什么? 運維服務于整個產品,保證架構合理,…

    Linux干貨 2015-03-11
  • Linux基于OpenSSL實現私有CA構建

    前言 隨著互聯網的迅猛發展,網絡通信已經成為傳遞信息的主要途徑。而通信時的數據傳輸大部分卻是明文傳輸的,在網絡這個不安全的環境下,如果沒有一套數據加密機制,就會導致敏感信息和重要數據泄露,引起不可估量的損失。而OpenSSL正好彌補了這一缺憾,那什么是OpenSSL呢?OpenSSL是一套強大的具有加密功能的組件,它包含libcrypto(公共加密庫)、li…

    Linux干貨 2015-04-13
欧美性久久久久