bash腳本入門之變量、運算、條件測試

概述

    腳本編程能力是作為運維工程師不可或缺的一項基本技能,各種系統的運維,如果完全靠命令行一條一條命令來執行,工作效率可想而知,而腳本卻可以將完成一定功能的各個命令依據一定的流程控制,邏輯判斷去完成某種功能,提升工作效率。本章就簡單介紹一些linux下的bash腳本編程的基礎入門知識,具體內容分為以下幾個方面:

    1、變量基礎

    2、運算基礎

    3、條件測試

    4、腳本練習

    

    

第一章    變量基礎

    1、變量的基礎定義

        <1>什么是變量?

            變量實際就是一段命名的內存空間,存儲著可能發生變化的數據

        <2>變量存儲的類型

            字符型、數值型(整型、浮點型)

        <3>各種編程語言對變量類型的定義要求

            強類型:定義變量時必須指定類型、參與運算必須符合類型

                要求;調用未聲明變量會產生錯誤

                如 java,python

            弱類型:無須指定類型,默認均為字符型;參與運算會自動

                進行隱式類型轉換;變量無須事先定義可直接調用

                如: bash 不支持浮點數

        <4>變量的命名規則

            a、不能使程序中的保留字:例如if, for;

            b、只能使用數字、字母及下劃線,且不能以數字開頭

            c、見名知義

            d、統一命名規則:駝峰命名法

                如:UserName  為大駝峰

                    userName  為小駝峰

        <5>Linux上變量的分類(根據變量的生效范圍等標準)

            本地變量:生效范圍為當前shell進程;對當前shell之外的其它shell進程,包括當前shell的子shell進程均無效

            環境變量:生效范圍為當前shell進程及其子進程

            局部變量:生效范圍為當前shell進程中某代碼片斷(通常指函數)

            位置變量: $1, $2, …來表示,用于讓腳本在腳本代碼中調用通過命令行傳遞給它的參數

            特殊變量: $?, $0, $*, $@, $#

    2、本地變量

        變量賦值: name=‘value’,

            (1) 可以是直接字串; name=“root"

            (2) 變量引用: name="$USER"

            (3) 命令引用: name=`COMMAND`, name=$(COMMAND)

        變量引用: ${name}, $name

            "":弱引用,其中的變量引用會被替換為變量值

            '':強引用,其中的變量引用不會被替換為變量值,而保持原字符串

        顯示已定義的所有變量: set(可顯示所有的變量,包括環境變量等,還包括定義的函數)

        刪除變量: unset name

    3、環境變量(下級進程都能使用)

        變量聲明、賦值:

            export name=VALUE

            declare -x name=VALUE

        變量引用: $name, ${name}

        顯示所有環境變量:export、env、printenv

        刪除: unset name

        bash有許多內建的環境變量,如:PATH, SHELL, USRE,UID,HISTSIZE, HOME, PWD,OLDPWD, HISTFILE, PS1等

    4、位置參數變量

        功能:在腳本代碼中調用通過命令行傳遞給腳本的參數

            $1, $2, …:對應第1、第2等參數, shift [n]換位置

         $0: 命令本身

            $*: 傳遞給腳本的所有參數,全部參數合為一個字符串

            $@: 傳遞給腳本的所有參數,每個參數為獨立字符串

         $@ $* 只在被雙引號包起來的時候才會有差異

            $#: 傳遞給腳本的參數的個數

                示例:判斷給出的文件的行數

                linecount="$(wc -l $1| cut -d' ' -f1)"

                echo "$1 has $linecount lines."

        變量的引用:直接$1,$2,當多位數最好用{}大括號引用起來,例如${21} 表示第21個位置參數變量

        $*表示全部的參數,當做一個整體來存儲

        $@表示全部的參數,將各個參數作為獨立的個體存儲

        區別如下所示:

        blob.png

        兩位數以上的位置參數變量的引用需要用{}大括號引用起來,例如

        blob.png

        blob.png

        

    5、只讀變量

        只讀變量:只能聲時,但不能修改和刪除(一般用來定義常量,例如定義pai=3.1415926),可定義為只讀變量后,可以再將其定義為環境變量,既是常量又是環境變量

        只讀變量的定義:

            readonly name

            declare -r name

        撤銷:

            unset name

第二章    運算基礎

    1、算數運算

        bash中的算術運算:

        +, -, *, /, %取模(取余) , **(乘方)

        實現算術運算:

            (1) let var=算術表達式

            (2) var=$[算術表達式]

            (3) var=$((算術表達式))

            (4) var=$(expr arg1 arg2 arg3 …)

                判斷變量整數:expr $VAR + 0  判斷整數

                在利用expr進行乘法計算時,*要轉義,寫成\*

                expr計算時,將后面計算式當做參數,故各個參數之間要有空格,引用expr結果時,要用“ 表示是命令引用

            (5) declare –i var = 數值

            (6) echo ‘算術表達式’ | bc

            bash有內建的隨機數生成器: $RANDOM( 1-32767)

            echo $[$RANDOM%50] : 0-49之間隨機數

        增強型賦值:

            +=, -=, *=, /=, %=

        let varOPERvalue

            例如:let count+=3  自加3后自賦值

        自增,自減:

             let var+=1

             let var++

             let var-=1

             let var–

            例如

            i=100

            let v=++i

            v的結果為101,(先自加+后=)如果let v=i++,則結果是v=100(先=后自加+)

    2、邏輯運算

        與:0與任何數都得0

        或:1或任何數都得1

        非:取反  

        短路運算:

            短路與:&&

                第一個為0,結果必定為0;

                第一個為1,第二個必須要參與運算;

            短路或:||

                第一個為1,結果必定為1;

                第一個為0,第二個必須要參與運算;

        異或:^

            異或的兩個值,相同為假,不同為真

        

    3、腳本的執行狀態結果 $?

        $? 變量保存最近的命令退出狀態

        一個命令是否執行成功,可以通過顯示$?的值來報告成功或失敗

            0 代表成功, 1-255代表失敗

        腳本退出狀態碼:(取決于腳本最后一條命令的執行狀態結果)

            exit [n]:自定義退出狀態碼;n的值為0-255之間

            注意:腳本中一旦遇到exit命令,腳本會立即終止;終止退出狀態取決于exit命令后面的數字

            注意:如果未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決于腳本中執行的最后一條命令的狀態碼

    4、運行腳本的不同方式的區別

        . 和source執行腳本時:沒有開子進程執行腳本,相當于直接在shell里面運行腳本里面的語句,故運行完腳本,腳本里面的變量在shell里依然有效

        bash和執行權限執行腳本:開了個子進程執行腳本,故腳本里面定義的變量,無法在shell里面繼續生效

        

        腳本里面某一條語句如果用()括號括起來,則表示該條語句新建一個子進程進行執行,執行完成后結果返回腳本里面

第三章    條件測試

    1、測試命令:

        test EXPRESSION

        [ EXPRESSION ]

        [[ EXPRESSION ]],一般字符串匹配都用這個

            注意: EXPRESSION前后必須有空白字符

        [[ $VAR ]] 可判斷變量是否有定義

        

        根據退出狀態而定,命令可以有條件地運行

            && 代表條件性的AND THEN

            || 代表條件性的OR ELSE

    2、數值測試:

        -gt: 是否大于;

        -ge: 是否大于等于;

        -eq: 是否等于;

        -ne: 是否不等于;

        -lt: 是否小于;

        -le: 是否小于等于;

    3、字符串測試:

        ==:是否等于;

        >: ascii碼是否大于ascii碼

        <: 是否小于

        !=: 是否不等于

        =~: 左側字符串是否能夠被右側的PATTERN所匹配

            注意: 此表達式一般用于[[ ]]中;

        -z "STRING":字符串是否為空,空為真,不空為假

        -n "STRING":字符串是否不空,不空為真,空為假

        注意:用于字符串比較時的用到的操作數都應該使用引號

    4、文件測試:

        存在性測試

            -a FILE:同-e

            -e FILE: 文件存在性測試,存在為真,否則為假;

        存在性及類別測試

            -b FILE:是否存在且為塊設備文件;

            -c FILE:是否存在且為字符設備文件;

            -d FILE:是否存在且為目錄文件;

            -f FILE:是否存在且為普通文件;

            -h FILE 或 -L FILE:存在且為符號鏈接文件;

            -p FILE:是否存在且為命名管道文件;

            -S FILE:是否存在且為套接字文件;

         文件權限測試:

             -r FILE:是否存在且可讀,判斷當前用戶對指定的文件是否有讀權限

             -w FILE: 是否存在且可寫,判斷當前用戶對指定的文件是否有寫權限

             -x FILE: 是否存在且可執行,判斷當前用戶對指定的文件是否有執行權限

         文件特殊權限測試:

             -g FILE:是否存在且擁有sgid權限;

             -u FILE:是否存在且擁有suid權限;

             -k FILE:是否存在且擁有sticky權限;

         文件大小測試:

              -s FILE: 是否存在且非空;

         文件是否打開:

             -t fd: fd表示文件描述符是否已經打開且與某終端相關

             -N FILE:文件自上一次被讀取之后是否被修改過

             -O FILE:當前有效用戶是否為文件屬主

             -G FILE:當前有效用戶是否為文件屬組

         雙目測試:

             FILE1 -ef FILE2: FILE1與FILE2是否指向同一個設備上的相同inode

             FILE1 -nt FILE2: FILE1是否新于FILE2;比較mtime

             FILE1 -ot FILE2: FILE1是否舊于FILE2;比較mtime

    5、組合測試條件

        第一種方式:

            COMMAND1 && COMMAND2 并且

            COMMAND1 || COMMAND2 或者

            ! COMMAND 非

           如: [ -e FILE ] && [ -r FILE ]

        第二種方式:

           EXPRESSION1 -a EXPRESSION2 并且

           EXPRESSION1 -o EXPRESSION2 或者

           ! EXPRESSION

        必須使用測試命令進行;

           # [ -z “$HOSTNAME” -o $HOSTNAME "=="localhost.localdomain" ] && hostname www.nwc.com

           # [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab

第四章    腳本練習

    1、編寫腳本/root/bin/systeminfo.sh,顯示當前主機系統信息,包括主機名,IPv4地址,操作系統版本,內核版本,CPU型號,內存大小,硬盤大小。

    #!/bin/bash            
    # Autor:nwc
    # Version:1.0
    # CreateTime:2016-08-11
    # Description:show the system info
            
    CPU=`cat /proc/cpuinfo |grep "model name"|cut -d ":" -f2 |head -1`
    HNAME=`hostname`
    IP=`ifconfig|sed -n '2p'|cut -d: -f2|cut -d" " -f1`
    OSRELEASE=`uname -sr`
    KERNEL=`uname -r`
    MEM=`cat /proc/meminfo|grep -i "memtotal"|tr -s ' '|cut -d: -f2`
    DISKSIZE=`fdisk -l|grep "Disk /dev/[sh]d"|cut -d: -f2|cut -d" " -f2|awk '{sum+=$1}END{print sum}'`
            
    echo "Hostname is: $HNAME"
    echo "IPv4 Address is: $IP"
    echo "OSRelease is: $OSRELEASE"
    echo "Kernel is: $KERNEL"
    echo "CPU is: $CPU"
    echo "MemSize is: $MEM"
    echo "DiskSize is: $DISKSIZE GiB"
    
    unset CPU
    unset HNAME
    unset IP
    unset OSRELEASE
    unset KERKNEL
    unset MEM
    unset DISKSIZE

     運行結果為:

    blob.png

    2、編寫腳本/root/bin/backup.sh,可實現每日將/etc/目錄備份到/root/etcYYYY-mm-dd中

    #!/bin/bash    
    # Autor:nwc
    # Version:1.0
    # CreateTime:2016-08-11
    # Description:backup etc to /root/etcYYYY-mm-dd
    
    cp -a /etc /root/etc`date +%F` && echo "backup etc success" || echo "backup etc fail"

    運行結果為:

    blob.png

    3、編寫腳本/root/bin/disk.sh,顯示當前硬盤分區中空間利用率最大的值

    #!/bin/bash    
    # Autor:nwc
    # Version:1.0
    # CreateTime:2016-08-11
    # Description:show the max used disk
    
    MaxDiskUsed=`df|grep "/dev/[sh]d"|tr -s ' ' '%'|cut -d% -f5|sort -nr|head -1`
    echo "Max Disk Used(%) is: $MaxDiskUsed"
    
    unset MaxDiskUsed

    運行結果為:

    blob.png

    4、編寫腳本/root/bin/links.sh,顯示正連接本主機的每個遠程主機的IPv4地址和連接數,并按連接數從大到小排序

    #!/bin/bash    
    # Autor:nwc
    # Version:1.0
    # CreateTime:2016-08-11
    # Description:show links
    
    LINK=`netstat -tn|grep "^tcp"|tr -s ' '|cut -d" " -f5|cut -d: -f1|grep -v "^$"|uniq -c|sort -nr`
    
    echo "$LINK"
    
    unset LINK

    運行結果為:

    blob.png

    5、寫一個腳本/root/bin/sumid.sh,計算/etc/passwd文件中的第10個用戶和第20用戶的ID之和

    #!/bin/bash    
    # Autor:nwc
    # Version:1.0
    # CreateTime:2016-08-11
    # Description:10 and 20 user UID sum
    
    # sumid=`sed -n -e '10p' -e '20p' /etc/passwd|cut -d: -f3|awk '{sum+=$1}END{print sum}'`
    
    id10=`sed -n '10p' /etc/passwd | cut -d: -f3`
    id20=`sed -n '20p' /etc/passwd | cut -d: -f3`
    sumid=$[${id10}+${id20}]
    echo "10&20 UID sum  $sumid"
    
    unset id10
    unset id20
    unset sumid

    運行結果為:

    blob.png

    6、寫一個腳本/root/bin/sumspace.sh,傳遞兩個文件路徑作為參數給腳本,計算這兩個文件中所有空白行之和

    #!/bin/bash    
    # Autor:nwc
    # Version:1.0
    # CreateTime:2016-08-11
    # Description: $1 and $2 blank lines sum
    
    space1=`grep "^$" $1|wc -l`
    space2=`grep "^$" $2|wc -l`
    sum=$[${space1}+${space2}]
    echo "$1 $2 blank lines sum is $sum"
    
    unset space1
    unset space2
    unset sum

    運行結果為:

    blob.png

    7、寫一個腳本/root/bin/sumfile.sh,統計/etc, /var, /usr目錄中共有多少個一級子目錄和文件

    #!/bin/bash    
    # Autor:nwc
    # Version:1.0
    # CreateTime:2016-08-11
    # Description: 
    
    ETC=`ls /etc|wc -l`
    VAR=`ls /var|wc -l`
    USR=`ls /usr|wc -l`
    sum=$[$ETC+$VAR+$USR]
    
    echo "sum is $sum"
    
    unset ETC
    unset VAR
    unset USR
    unset sum

    運行結果為:

    blob.png

    8、寫一個腳本/root/bin/argsnum.sh,接受一個文件路徑作為參數;如果參數個數小于1,則提示用戶“至少應該給一個參數”,并立即退出;如果參數個數不小于1,則顯示第一個參數所指向的文件中的空白行數

    #!/bin/bash    
    # Autor:nwc
    # Version:1.0
    # CreateTime:2016-08-11
    # Description:
    
    [ $# -lt 1 ] && echo "at least one argu" || echo " $1 blank lines is `grep "^$" $1|wc -l`"

    運行結果為:

    blob.png

    

    9、寫一個腳本/root/bin/hostping.sh,接受一個主機的IPv4地址做為參數,測試是否可連通。如果能ping通,則提示用戶“該IP地址可訪問”;如果不可ping通,則提示用戶“該IP地址不可訪問”

    #!/bin/bash    
    # Autor:nwc
    # Version:1.0
    # CreateTime:2016-08-11
    # Description:
    
    ping -c1 -W1 $1 &>/dev/null && echo "$1 is up" || echo "$1 is down"

    執行結果為:

    blob.png

    10、chmod -rw /tmp/file1,編寫腳本/root/bin/per.sh,判斷當前用戶對/tmp/fiile1文件是否不可讀且不可寫

    #!/bin/bash    
    # Autor:nwc
    # Version:1.0
    # CreateTime:2016-08-11
    # Description:
    
    [ ! -r /tmp/file1 -a ! -w /tmp/file1 ] && echo "have no right rw" || echo "have right r or w or rw"

    運行結果為:

    blob.png

    blob.png

    11、編寫腳本/root/bin/nologin.sh和login.sh,實現禁止和充許普通用戶登錄系統。

    #!/bin/bash    
    # Autor:nwc
    # Version:1.0
    # CreateTime:2016-08-11
    # Description: nologin
    
    [ -f /etc/nologin ] && echo "already can not access" || (touch /etc/nologin && echo "create /etc/nologin success")

    nologin的執行結果

    blob.png

    #!/bin/bash    
    # Autor:nwc
    # Version:1.0
    # CreateTime:2016-08-11
    # Description:login
    
    [ -f /etc/nologin ] && (rm -f /etc/nologin ; echo "delete /etc/nologin success") || echo "already can access"

    login執行結果

    blob.png

    12、寫一個腳本/root/bin/hostping.sh,接受一個主機的IPv4地址做為參數,先判斷是否合格IP,否,提示IP格式不合法并退出,是,測試是否可連通。如果能ping通,則提示用戶“該IP地址可訪問”;如果不可ping通,則提示用戶“該IP地址不可訪問”

    #!/bin/bash    
    # Autor:nwc
    # Version:1.0
    # CreateTime:2016-08-11
    # Description: ping a IP addr
    
    echo "$1"|grep -E "\<(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[1-4][0-9]|25[0-5])\.){3}
    ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[1-4][0-9]|25[0-5])\>" &>/dev/null && (ping -c1 -W1 $1 &>/dev/null && echo "$1 is up" 
    || echo "$1 is down") || echo "$1 is not a IP addr"

    執行結果如下:

    blob.png

    13、計算1+2+3+…+100的值

    #!/bin/bash    
    # Autor:nwc
    # Version:1.0
    # CreateTime:2016-08-11
    # Description:the sum of all args
    
    echo "`echo "$@"|tr -s ' ' '+'`"|bc

     執行結果如下:

    blob.png 

  

    14、計算從腳本第一參數A開始,到第二個參數B的所有數字的總和,判斷B是否大于A,否提示錯誤并退出,是則計算之

    #!/bin/bash    
    # Autor:nwc
    # Version:1.0
    # CreateTime:2016-08-11
    # Description: sum between arg1 to arg2
    
    [ $2 -ge  $1 ] && seq $1 $2|tr -s '\n' '+'|sed -r 's@(.*)\+$@\1\n@'|bc || echo "Error args"

    運行結果為:

    blob.png

原創文章,作者:M20-1倪文超,如若轉載,請注明出處:http://www.www58058.com/33512

(0)
M20-1倪文超M20-1倪文超
上一篇 2016-08-12 14:45
下一篇 2016-08-12 14:45

相關推薦

  • 網絡基礎知識

    網絡基礎知識: 網絡設備 TCP/IP協議 ARP協議 網絡設備:     HUB集線器: 工作在物理層,沒有學習能力,作用在于把各種節點匯聚在以它為中心的節點上,同時也有傳輸數據的作用,由于沒有學習能力,只能以廣播的形式將數據發送給與它相連的所有節點。 特點:共享帶寬,半雙工     &…

    Linux干貨 2016-09-02
  • N25 – Week 4 blog

    第四周博客作業了,感覺前面的有好多都忘掉了,但是沒有時間補以前的啊……好郁悶,幸好今天周五,明天又是圣誕節,從馬云爸爸買了一顆圣誕樹,今晚回家裝上 1. 復制/etc/skel目錄為/home/tuser1,要求/home/tuser1及其內部文件的屬組和其他用戶均沒有任何訪問權限 [root@dhcp-10-129-6-166&nb…

    Linux干貨 2016-12-20
  • 【超全整理】《Linux云計算從入門到精通》系列實戰筆記全放送

    ? ? ? 為了方便Linux云計算愛好者的學習查看,馬哥Linx云計算團隊特別整理了《Linux云計算從入門到精通》年度重磅大放送,囊括了整個學習過程的學習精華,內容全部由馬哥Linux云計算學員撰寫,歡迎大家支持?。?! ? ? ? 詳情請看: ?一、Linux運維基礎實戰入門 從Linux0基礎入門開始,全面講解作為新手如何學習Linux,以及學習方法和…

    2017-09-14
  • 【原創】Tengine+LUA+Nginx-GridFS+jemalloc編譯安裝

    操作系統 ubuntu 14.04 LTS Nginx-GridFS為nginx直接訪問mongoDB的擴展模塊,目前只支持到mongodb2.6.12 mongodb安裝請自己百度 #安裝依賴包保平安 apt-get install root-system-bin autoconf automake gcc c++ libgeoip-devlibxml++…

    Linux干貨 2016-11-30
  • N21沉舟11周作業

    1、請描述一次完整的http請求處理過程; (1) 建立或處理連接:接收請求或拒絕請求 (2) 接收請求: (3) 處理請求:對請求報文進行解析,并獲取請求的資源及請求方法等相關信息 (4) 訪問資源:獲取請求報文中請求的資源 (5) 構建響應報文 (6) 發送響應報文 (7) 記錄日志 …

    Linux干貨 2016-09-26
  • X86平臺系統啟動流程 (Blog 9)

    POST –> BootSeqence(BIOS) –> Bootloader(MBR) –> Kernel(initrd) –> init(/etc/inittab)

    2017-11-27

評論列表(2條)

  • yashan
    yashan 2016-08-13 07:55

    只讀變量不能銷毀

  • 馬哥教育
    馬哥教育 2016-08-16 14:29

    寫的很詳細,態度很端正,對各位置變量,通過腳本來進行驗證,思路也很清晰,再接再厲。

欧美性久久久久