bash腳本編程基礎知識

shell腳本語言編程之bash

shell簡介

什么是shell:
    shell是Linux的用戶界面,提供了用戶與內核進行交互的接口,他接收了用戶的指令,并將指令送入內核去執行
    shell即是一種高級程序語言,也是一種命令解析語言
    
shell腳本有點:
    開發簡單、可移植性強(使用POSIX所定義的功能)、簡單性
    
shell編程:
    用于系統管理工作,或是結合現有的程序或命令完成小型的或特定的工作。
    
編程語言分類以及工作原理
    
  編譯語言:高級語言-- >編譯器-- >目標代碼 
    編譯語言源代碼運行時需要編譯器轉換成程序文件,編譯語言舉例: java, C#
  解釋語言:高級語言-- >解釋器-- >機器代碼
    由解析器直接讀入代碼,將其轉換成內部形式 ,解析語言舉例:shell, perl, python
  
編譯模型:
    過程式:以指令為中心,數據服務于代碼
    面向對象式:以數據為中心指令服務于數據
   
shell編程格式:
    首行shebang機制
    #!/bin/bash
  
 shell腳本用途:
     
     自動化常用命令
     執行系統管理和故障排除
     創建簡單的應用程序
     處理文本或文件

創建shell腳本

    
    第一步:創建本文文件,首行添加#!/bin/bash
                    #注釋
    第二步:運行腳本

shell腳本運行

       
        一、給予執行權限,在命令行上指定腳本的絕對或相對路徑
        二、直接運行解釋器,將腳本作為解釋器程序的參數運行

   1.png

   2.png

shell腳本第一個實例:hello word

   shell.png

bash腳本調試

    
    bash - n /path/to/some_script
    檢測腳本中的語法錯誤
    bash - x /path/to/some_script
    調試執行

腳本變量

    
    變量:命名的內存空間
         數據存儲方式:
         字符:
         數值:整型,浮點型
       
        作用:
            1、數據存儲格式
            2、參與的運算
            3、表示的數據范圍
            
        類型:
        字符
        數值:整型、浮點型
    變量命名法則:
        1、不能使程序中的保留字:例如if, for;
        2、只能使用數字、字母及下劃線,且不能以數字開頭
        3、見名知義
        4、統一命名規則:駝峰命名法
    
    shell中變量屬于弱引用,無須指定類型,默認均為字符型;參與運算會自動進行隱式類型轉換;變量無須事先定義可直接調用
            如: bash 不支持浮點數
            
    bash中的變量種類
        本地變量:僅對當前shell進程生效
        環境變量:對當前shell以及子shell生效
        局部變量:生效范圍為當前shell進程中某代碼片斷(通常指函數)
        位置變量:$1, $2, ...來表示,用于讓腳本在腳本代碼中調用通過命令行傳遞給它的參數
        特殊變量:$?, $0, $*, $@, $#

本地變量

    變量賦值: name=‘value’,
        以下是變量可引用的值:
               1、可以是直接字串:name=“root"(注意等號左右兩邊不能有空格哦)
               2、變量引用:name="$USER"
               3、命令引用:name=`COMMAND`, name=$(COMMAND)
               
       變量引用: ${name}, $name
           三種引號使用!?。。。?
        "":弱引用,其中的變量引用會被替換為變量值
        '':強引用,其中的變量引用不會被替換為變量值,而保持原字符串
        ``:能識別命令
        
       顯示已定義的所有變量: set
       刪除變量: unset name


證明環境變量只能在當前shell中使用

在當前shell中定義變量name=wangNN ——>在打開一個子shell輸出name變量為空
    pstree :顯示進程樹??梢圆榭串斍敖K端shell的結構

    6.png



bash腳本編程小試牛刀:

  
  1、編寫腳本/root/bin/systeminfo.sh,顯示當前主機系統信息,包括主機名, IPv4地址,操作系統版本,內核版本,CPU型號,內存大
  硬盤大小。
[root@centos7 bin]# cat systeminfo.sh 
#!/bin/bash
echo "the hostname is:`hostname`"
echo "localhost IPV4 is:`ifconfig |sed -n "2p" |sed -e "s@.*inet@@" -e "s@netmask.*@@" `"
echo "the operation bersion is:`cat /etc/centos-release`"
echo "the kenel information is:`uname -r`"
echo "the cpu is:`lscpu |head -1|sed "s@.*[[:space:]]\+\b@@"`"
echo "the member size is:`cat /proc/meminfo |head -1 |tr -s " "|cut -d " " -f 2,3`"
echo "the hard /dev/sda size is:`fdisk -l |grep sda|head -1|sed "s@.*:@@"|sed "s/,.*//"`"
echo "the hard /dev/sdb size is:`fdisk -l |grep sdb|head -1|sed "s@.*:@@"|sed "s/,.*//"`"
[root@centos7 bin]#
2、編寫腳本/root/bin/backup.sh,可實現每日將/etc/目錄備份到/root/etcYYYY- mm- dd中

    3.png

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

    4.png

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

    5.png

環境變量

變量聲明和賦值
    export name="value"
    declare -x 變量名=值
變量引用
    $name ${name}
      
顯示所有環境變量
    env
    export
    printenv
    
   
刪除變量:unset 變量名

證明環境變量可以在子shell中應用

    定義環境變量——>bash 進入子shell ——>echo $name發現變量有值

    7.png

只讀變量:

  只讀變量:只能聲明,不能刪除,退出當前shell之后自動消失

  8.png

位置參數變量

 
    $?:上一條執行命令結果,0成功1代表失敗
  $0:當前shell類型                
  $@:將傳遞的參數展開成多個參數
    $*:將傳遞的參數作為一個整體           
    $#:目前進程中的參數個數

   $*和$@區別

   $*和$@都指傳遞多個參數,單獨打印時,不能看出區別,當下一個腳本調用時$@ 將傳遞的參數展開成多個,$*將多個參數捆綁在一起

   只有添加" "他們才會有區別,不加" "$*默認將多個參數展開成多個參數進行傳遞

    9.png

bash中的算數運算符

    +, - , *(使用時需要\進行轉義), /, %取模(取余) , **(乘方)
    bash 中實現算數運算的幾種方法:
    1、let var=算數表達式
    2、var=$[算數表達式]
    3、var=$((算數表達式))
    4、var=$(expr $num1 + $num2 ) 
    5、declare -i var=數值
        echo "算數表達式" |bc (如果是數值 1+2 可以是用'',如果引用的是變量就要使用"$num1+$num2")
   bash有內建的隨機數生成器: $RANDOM( 1 - 32767)
   echo $[$RANDOM%50] : 0- 49之間隨機數

 實現算數運算的方法

    1、使用let
        let:求算是表達式中的值

    bash腳本編程基礎知識

  2、使用[]
      [:內置命令,判斷條件表達式,與test同義,但是必須使用]結尾。

    bash腳本編程基礎知識

   3、使用(())

    bash腳本編程基礎知識

    4、使用expr
           expr :只能計算整數,并且表達式每個參數之間要添加空格

    15.png

賦值

     增強型賦值:
        +=, - =, *=, /=, %=
        let count+=3 自加3后自賦值
         自增,自減:
        let var+=1
        let var++
        let var- =1
        let var--

練習二

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

    [root@centos7 bin]# cat sumid.sh 
    #!/bin/bash
    #author:wangNanNan
    #time:20160810
    #fuction:calculate the sum of the two userID
    userID1=`cat /etc/passwd |sed -n "10p" |cut -d: -f3`
    userID2=`cat /etc/passwd |sed -n "20p" |cut -d: -f3`
    SUM=$[userID1+userID2]
    echo "the sum of he tenth userID and the twenth usrID is:$SUM"
    unset userID1
    unset userID2
    unset SUM
    [root@centos7 bin]#

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

   
    [root@centos7 bin]# cat sumspace.sh 
    #!/bin/bash
    #author:wangnannan
    #time:20160810
    #function:calculate the sumspace of the two file
    fistFileSpace=`grep -c '^$' $1 `
    secondFileSpace=`grep -c '^$' $2 `
    sum=$[ fistFileSpace + secondFileSpace ]
    echo "兩個文件空白行之和為:$sum"
    unset fistFileSpace
    unset secondFileSpace
    unset sum
    [root@centos7 bin]#

 練習 3:寫一個腳本/root/bin/sumfile.sh,統計/etc, /var,/usr目錄中共有多少個一級子目錄和文件
    17.png 

邏輯運算符

    非:! 與:& 或:|


    與:兩個數字或條件進項進行與運算,其中有一個為假,結果為假

    或:兩個數字或條件進項進行與運算,其中有一個為真,結果為真

   

   
     短路與:
    第一個為0,結果必定為0;
    第一個為1,第二個必須要參與運算;
    短路或:
    第一個為1,結果必定為1;
    第一個為0,第二個必須要參與運算;
    異或: ^
    異或的兩個值,相同為假,不同為真


聚合命令

   
    復合式: date; who | wc - l
        命令會一個接一個地運行
    ? 子shell: 
        (date; who | wc - l ) >>/tmp/trace所有的輸出都被發送給單個STDOUT和STDERR

退出狀態

   
   進程使用退出狀態來報告成功或失敗
        0:代表成功
        1-255:代表失敗
    
    例如:
    $ ping - c1 - W1 hostdown &> /dev/null
    $ echo $?
    
    自定義bash退出狀態碼
        exit[n];
        shell 腳本遇到exit,會立即退出,退出狀態碼取決于exit[]后面的數字,如果未定義,取決于腳本最后一條命令執行的狀態碼

條件測試

    

 

   測試命令:
        ? test EXPRESSION
        ? [ EXPRESSION ]
        ? [[ EXPRESSION ]]
        注意: EXPRESSION前后必須有空白字符
 
     test命令:檢測文件類型或比較值是否相等
         格式:test 表達式
     test命令兩種格式:
         長格式:test $A=$B
         短格式:[ "$A" == "$B" ] 
     
     數值類測試:
         -eq:是否等于
         -ge:是否大于等于
         -le:是否小于等于
         -gt:是否大于
         -lt:是否小于
         -ne:是否不等于
         
    字符串類測試:
        ==:是否等于;
        >: ascii碼是否大于ascii碼
        <: 是否小于
        !=: 是否不等于
        =~: 左側字符串是否能夠被右側的PATTERN所匹配,此表達式一般用于[[ ]]中;
        - z "STRING":字符串是否為空,空為真,不空為假
        - n "STRING":字符串是否不空,不空為真,空為假
        注意:用于字符串比較時的用到的操作數都應該使用引號

練習題:

1、寫一個腳本/root/bin/argsnum.sh,接受一個文件路徑作為參數;如果參數個數小于1,則提示用戶“至少應該給一個參數”,并立即退出;
如果參數個數不小于1,則顯示第一個參數所指向的文件中的空白行數
    
    [root@centos7 bin]# cat argsum.sh 
    #!/bin/bash
    #author=wangnannan
    #time=20160810
    #function:argument count
    [[ $# -lt 1 ]] && echo "Should at least give a parameter;`exit`" || echo "the first file Blank row :`grep -c "^$" $1`"
    [root@centos7 bin]#
2、寫一個腳本/root/bin/hostping.sh,接受一個主機的IPv4地址做為參數,測試是否可連通。如果能ping通,則提
示用戶“該IP地址可訪問”;如果不可ping通,則提示用戶“該IP地址不可訪問 ”

    [root@centos7 bin]# cat hostping.sh 
    #!/bin/bash
    #author:wangnannan
    #time20160810
    #fuction:test one host can bi communicate
    echo -e "please input the ipv4\c"
    read ipv4
    ping -c1 $ipv4 && echo "the host can be arrive" || echo "the host no arrive"
    [root@centos7 bin]#


文件測試

    存在性測試
        - 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;
            FILE1 - ot FILE2: FILE1是否舊于FILE2;

    文件測試小練習:

        1、檢測文件是否存在

        18.png

          2、檢測兩個文件是否為硬鏈接

        

        19.png


組合測試:

    
    第一種方式:
        COMMAND1 && COMMAND2 并且
        COMMAND1 || COMMAND2 或者
        ! COMMAND 非
        如: [ - e FILE ] && [ - r FILE ]
        
    第二種方式:
        EXPRESSION1 - a EXPRESSION2 并且
        EXPRESSION1 - o EXPRESSION2 或者
        ! EXPRESSION
        必須使用測試命令進行;
        
        [ - z “$HOSTNAME” - o $HOSTNAME "==\"localhost.localdomain" ] && hostname www.magedu.com

練習題

1、 chmod - rw /tmp/file1,編寫腳本/root/bin/per.sh,判斷當前用戶對/tmp/fiile1文件 是否不可讀且不可寫
    
    [root@centos7 bin]# cat per.sh 
    #!/bin/bash
    [ ! -r /tmp/file1 -a ! -w /tmp/file1  ] && echo "`whoami` can not  read and not write " || 
    echo  "`whoami` can  read or  write "

    [root@centos7 bin]#
    注意:在普通用戶下去運行,root不受權限限制
    
2、編寫腳本/root/bin/nologin.sh和login.sh,實現禁止和充許普通用戶登錄系統。
    
    [root@centos7 bin]# cat login.sh 
    #!/bin/bash
    [ -a /etc/nologin ] && echo "common user is not login" || (touch /etc/nologin;echo "add file complete")
    [root@centos7 bin]#

使用read命令接受輸入參數

    read [option]

    -p:不換行接受輸入

    -t:接受輸入時間,超過指定時間將推出程序


終極練習

1、指定文件做為參數,判斷文件是否為.sh后綴,如果是,添加x權限
    
    [root@centos7 bin]# cat file.sh 
    #!/bin/bash
    echo -e  "please input filename:\c"
    read filename
    ! [ -e $filename ] && echo "the file not exit;" && exit
    ! [[ $filename == "/.*(\.sh)\b/" ]] && echo "please input .sh file;`exit`"
    [ -x $filename ] && echo "the file have x" || chmod +x $filename 
    [root@centos7 bin]#
2、判斷輸入的IP是否為合法IP
    [root@centos7 bin]# cat ipcheck.sh 
    #!/bin/bash
    #author:wangnannan
    read -p "please input IPv4:" ipv4
    echo $ipv4 |egrep -q  "^(\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>.){3}\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>$" 
    && echo "ip legal" || echo "this ip is not legal"
    [root@centos7 bin]# vim ipcheck.sh
    [root@centos7 bin]#

 3、計算1~100的值

    [root@centos7 bin]# cat sum100.sh 
    #!/bin/sh
    #author:wangnannan
    #description:sum 1-100
    echo "caculate 1-100 sum:"
    for i in {1..100};do
	sum=$[$sum+$i]
	done
    echo "sum is:$sum"
    exit
    [root@centos7 bin]# 
    
    
    方法二
    [root@centos7 bin]# cat sum1002.sh 
    #!/bin/bash
    int=`seq 1 100`
    echo $int |tr " " "+" |bc
    [root@centos7 bin]# 

    
    方法三
    
    [root@centos7 bin]# seq -s + 1 100 |bc
    5050
    [root@centos7 bin]#
4、輸入起始值A和最后值B,計算從A+(A+1)...+(B-1)+B的總和
    [root@centos7 bin]# cat AB.sh 
    #!/bin/bash
    read -p "plese the first num:" A
    read -p "plese the second num:" B
    [ $A -gt $B ] && echo "input error" && exit ||echo "A..B的和:` seq  -s + $A $B |bc`"
    [root@centos7 bin]#

原創文章,作者:wangnannan,如若轉載,請注明出處:http://www.www58058.com/33909

(0)
wangnannanwangnannan
上一篇 2016-08-15
下一篇 2016-08-15

相關推薦

  • 包管理之包查詢,包校驗,rpm數據庫.yum的詳細用法及說明

    一.概述 包查詢 rpm {-q|–query} [select-options] [query-options] [select-options] -a: 所有包 -f: 查看指定的文件由哪個程序包安裝生成 -p rpmfile:針對尚未安裝的程序包文件做查詢操作; –whatprovides CAPABILITY:查詢指定的CAP…

    Linux干貨 2016-08-30
  • N26_第一周

    計算機組成     CPU:核心部件:                 運算器: 對數據進行算術運算和邏輯運算     …

    Linux干貨 2017-01-11
  • 第六周小練習

    詳細總結vim編輯器的使用并完成一下練習 vim編輯器的基本使用 vim模式: 1、編輯模式(命令模式) 2、輸入模式 3、末行模式  一、打開文件 vim /path/to/somefile 打開單個文件 如果文件存在為打開,否則保存退出時為新建 vim /path/to/somefile vim +# : 打開文件…

    Linux干貨 2016-12-19
  • 系統管理之程序包管理(一) rpm詳解

    系統管理之程序包管理(1):     程序包管理是運維人員的基本工作素質之一。在操作系統上,不斷的安裝,卸載,配置應用程序包,讓不同程序包運行提供不同的服務;利用某種工具完成某些操作的過程。這就要求運維工作人員熟悉安裝,管理應用程序包。 在linux上,程序包主要有兩種:tar,rpm包。 一、程序包概述: 系統接口   &nb…

    Linux干貨 2016-08-21
  • zabbix表分區(適用于zabbix2.0.x,zabbix2.2.x和zabbix2.4.x)

    本文主要介紹了zabbix進行數據庫表分區的方法:         在系統監控中,zabbix已經代替了nagios+cacti,zabbix以其良好的圖形展示和高度自定義贏得了很多運維人員的喜愛。但是由于在工作中,zabbix跑的時間過長(我們公司跑了將近3年),web頁面經??D,監控…

    Linux干貨 2015-10-27
  • jenkins+gitlab構建安卓自動編譯環境

        因工作關系接觸到接觸到安卓自動編譯環境,網上的資料都推薦了jenkins,因為第一次接觸安卓和jenkins,踩了不少的坑,有總結才有進步。    gitlab環境之前已經安裝完成可用,具體步驟另外詳解吧。本例目標是在gitlab可用前提下,通過jenkins將git倉庫的代碼自行編譯打包,生成可用的apk安裝…

    Linux干貨 2016-07-16

評論列表(1條)

  • 馬哥教育
    馬哥教育 2016-08-15 12:50

    文章內容清晰,圖文并貌,內容豐滿,有理論有實踐,

欧美性久久久久