Shell腳本編程

shell腳本編程

Bash為用戶提供了編程環境

相對于計算機而言,只能識別二進制文件,因此其所運行的其實是二進制指令,而這些二進制指令我們稱之為機器語言,屬于低級語言;程序員編程所使用的語言為高級語言,是人們比較容易理解的語言;因此,程序的執行過程:先把源碼程序翻譯成機器語言(生成可執行的文件),然后解釋執行。
程序( 程序=指令+數據 )的編程風格有兩種:

  • 面向過程的編程:以指令為中心,數據服務指令
    面向對象的編程:以數據為中心,指令服務數據;

shell程序是一個過程式的解釋器,提供了編程能力,然后解釋執行;對于過程式編程而言,把一行源碼程序翻譯成機器語言,然后執行,再翻譯下一行的源碼程序為機器語言,然后執行;

  • 編譯過程:高級語言–>編譯器–>目標代碼 
    需要提前編譯,編譯成機器可以理解二進制文件,然后再執行
    靠近底層,執行效率非常高,跨平臺性比較差
    C++ CentOS—-> SuSE(騰訊云)
    C#(微軟) 只能在windows運行 
    IIS C# .net SQLServer
    Golang
  • 解釋過程:高級語言–>解釋器–>機器代碼
    并不需要提前編譯,只需要把代碼轉換成中間代碼,邊解釋邊運行
    執行效率稍遜,跨平臺
    JAVA、 Python 、Shell 、PHP 、Ruby

shell腳本:

shell腳本其實就是一系列命令組合起來的文本文件,利用這些命令組合起來完成一個或者一項功能;

  • shell腳本開頭環境的指定:

    #!/bin/bash
    #
    #Filename:BeiFen.sh
    #Description:Test
    #Author:Li Nan
    #Email:xxx@126.com
    #Revision:3.1
    #Date:20170407
    #Note:Test

    # 表示注釋,此行不執行

  • shell腳本組成:
    變量
    命令
    控制語句(if、for、while)

  • 運行腳本:
    1、給予執行權限,通過具體的文件路徑對指定文件執行;

    • 加執行權限
      1)相對路徑
      2)絕對路徑
      3)放到$PATH變量指定的目錄里面,直接執行(tab)

    2、直接運行解釋器,將腳本作為解釋器程序的參數運行;

    • bash、sh

    3、腳本調試執行:

    • bash -n 檢查語法錯誤,不檢查拼寫錯誤
      bash -x 顯示腳本執行的時候每一個命令具體的執行結果

變量

  • 變量:命名的內存空間
  • 數據存儲的方式:字符、數值;
  • 變量的作用:

    • 1、數據存儲格式
      2、參與的運算
      3、表示的數據范圍

變量的類型:

  • 字符
    數值:整型、浮點型
    注:相同類型的數據在一起才可以進行運算,數值型和字符型不能運算

  • 對于編程語言來說還分為:強類型、弱類型;

    • 強類型:JAVA C# 
      數值型和字符型不能直接計算
      除非顯式 把字符型轉換成數值型才可以計算

      C++ 
      int a=10;
      char a=10
      double b=10

    • 弱類型 :shell php
      不會嚴格區分變量類型
      定義變量的時候不用指定變量類型,默認字符型
      如果想要計算的時候,會自動幫你轉換成數值型

      Shell
      I=10
      J=2

變量的命名規則:

  1. 不能使用if for bash cd ls date關鍵字
  2. 不能以數字開頭,不能使用特殊符號
    只能使用數字 字母及下劃線
  3. 見名知義
  4. 建議變量使用大寫

bash變量的種類

  • 本地變量(全局變量): 僅僅對當前shell生效

    • 變量的賦值:name=’value’
      value 可以使用引用:

      1、可以直接使用字符串;name = “username”
      2、變量引用:name = “$username”
      3、命令引用:name=COMMAND,name=$(COMMAND)

    • 變量引用:$name、${name}
      “” :弱引用 會把雙引號里面的變量替換
       ”  :強引用 不會把引號里面的變量進行替換
      “ : 把反引號里面的命令執行結果賦值給變量
      HZ=$SH 用變量賦值變量

    • 顯示已定義的所有變量:set

    • 取消變量:unset name

      • 取消變量和變量置空是兩種不同概念
        unset HZ
        HZ=
  • 環境變量 : 對當前shell以及其他shell都生效,使用export可使變量改變為環境變量
    子shell只會繼承環境變量,并不會繼承父shell中的變量

    • 變量聲明、賦值:

      1. export name = VALUE
      2. name = VALUE
        export name
      3. declare -x name = VALUE
      4. name = VALUE
        declare -x name
    • 變量引用:$name、${name}

    • 顯示所有環境變量:export、env、printenv、declare -x 、set
    • 取消變量:unset name

Bash中有很多內建的環境變量(大寫):PATH,SHELL,UID,HISTSIZE,PWD,OLD,HISTFILE,PS1等。

  • 局部變量(私有變量) :通常用在函數里面,使用local定義
  • 位置變量:$1,$2,…$n,${10}來表示,用于放在腳本代碼中調用通過命令行傳遞給它的參數;
    shift + [n] 換位置
  • 特殊變量: 
    $?:上個命令執行成功與否的結果
    $0:表示命令本身
    $#:傳遞給腳本參數的個數
    $*:傳遞給腳本的所有參數,(全部參數合為一個字符串)
    $@:引用傳遞給腳本的所有參數,(每個參數為獨立字符串)
    當被括號括起來的時候會看出區別
    $$:顯示此腳本的進程號

  • 只讀變量:
    只能聲明,但不能修改和刪除
    聲明只讀變量:
    readonly name
    declare -r name
    查看只讀變量:
    readonly -p

變量的高級操作

  • 字符串切片

    • ${變量:位置起點}
      由指定的位置開始,截取字符串到字符串結束
    • ${變量:位置起點:長度}
      eg:MYNAME=”123456789″
      substr2=${MYNAME:4:6}
    • 計算字符串長度
      ${#變量名稱}
      傳回變量值的字符串長度
      filename=”/usr/sbin/ntpd”
      ehco ${#filename}

      PS:另一種方法:
      expr length “$filename”

    • 由前面(最左邊)開始,對比變量值,刪除“最短相符合的字符串”
      ${變量#樣式}
      filename=”/usr/sbin/ntpdate”
      echo ${filename#/*/}

    • 由前面對比,刪除最長的
      ${變量##樣式}
      filename=”/usr/sbin/ntpdate”
      echo ${filename##//}


      • 由后面對比,刪除最短的

        ${變量%樣式}

        filename=”/usr/sbin/ntpd”

        echo ${filename%/}

      • 由后面對比,刪除最長的

        ${變量%%樣式}

        domainname=”www.www58058.com”

        echo ${domainname%%.*}

    • 只替換第一個對比符合的字符串
      ${變量/樣式/替換字符串}
      name=”liangchenye”
      echo ${name/liang/wang}
    • 替換全部對比符合的字符串
      ${變量//樣式/替換字符串}
      name=”zhaoritian”
      echo ${name//zhao/ye}
    • 把對比符合的字符串刪除
      只刪除一個
      ${變量/樣式/}
      name=”liangchenye”
      echo ${name/liang/}
    • 把對比符合的字符串全部刪除
      ${變量//樣式/}
      name=”zhaoritian”
      echo ${name//zhao/}
  • 測試存在性及空值

    • ${待測變量-默認值}
      若變量不存在,則符合判斷,傳回默認值
      unset myname
      echo ${myaname-“fuerkang”}
    • ${待測變量:=默認值}
      若變量不存在或其值為空,則符合判斷,傳回默認值
      unset myname
      echo ${myname:=”fuerkang”}
    • 測試變量是否為空或者不存在,提示錯誤信息
      ${待測變量:?提示信息}
      echo ${name:?”sorry no name”}
    • 測試變量的存在性,若存在且非空,則符合判斷
      ${待測變量:+”ture”}
      echo ${magedu:+”true”}

算數運算

bash會對數字執行隱式的類型轉換

  • 運算操作符:+、-、、/、%(取余)、*(乘方)
    bash運算的實現方式:

    • (1) let num=算術表達式 ,let r=9+9
      (2) var=$[算術表達式] , r=$[9+9]
      (3) var=$((算術表達式)) , r=$((9+9))
      (4) 外部命令:expr 8 + 3 (+ 兩邊要有空格)
      (5)declare -i,declare -i r=9+9
      (6)bc ,echo {1..100} | tr ” ” “+” | bc

    注意 :expr 8 * 8 ;乘號需要轉義

    • (7)echo $((12+$i))是否可以執行
      建議把$i中的$去掉
      正確姿勢 echo $((12+i))
    • bash內建的隨機數生成器,$RANDOM (0-32767)
      echo $[$RANDOM%50]:0-49之間的隨機數
  • 賦值

    • 增強型賦值:
      +=, i+=3等于i=i+3 
      -=, i-=3等于i=i-3
      =, i=3等于i=i*3
      /=, 
      %=
    • 自增、自減:
      ++ 先執行 執行完加1 (用的比較多)
      ++i 先加1,再執行
      var=$[$var+1]–>let var+=1 –> let var++

    [root@Centos7 script]# a=10
    [root@Centos7 script]# b=10
    [root@Centos7 script]# let c=a++
    [root@Centos7 script]# echo $c
    10
    [root@Centos7 script]# echo $a
    11
    [root@Centos7 script]# let d=++b
    [root@Centos7 script]# echo $d
    11
    [root@Centos7 script]# echo $b
    11

字體顏色

  • 字體顏色:30——37
    echo -e “\033[30m 黑色字 \033[0m” 
    echo -e “\033[31m 紅色字 \033[0m” 
    echo -e “\033[32m 綠色字 \033[0m” 
    echo -e “\033[33m 黃色字 \033[0m” 
    echo -e “\033[34m 藍色字 \033[0m” 
    echo -e “\033[35m 紫色字 \033[0m” 
    echo -e “\033[36m 天藍字 \033[0m” 
    echo -e “\033[37m 白色字 \033[0m”

  • 字體背景顏色40—–47
    echo -e “\033[40;37m 黑底白字 \033[0m” 
    echo -e “\033[41;37m 紅底白字 \033[0m” 
    echo -e “\033[42;37m 綠底白字 \033[0m” 
    echo -e “\033[43;37m 黃底白字 \033[0m” 
    echo -e “\033[44;37m 藍底白字 \033[0m” 
    echo -e “\033[45;37m 紫底白字 \033[0m” 
    echo -e “\033[46;37m 天藍底白字 \033[0m” 
    echo -e “\033[47;30m 白底黑字 \033[0m”

邏輯運算

true (1)、false (0)
命令執行成功 我們認為是真 
命令執行失敗 我們認為是假

  • 與運算:&&
    1 && 1 = 1
    1 && 0 = 0
    0 && 1 = 0
    0 && 0 = 0
    與的時候 只要有一個為假 那么整個結果就是假的。

  • 或運算:||
    1 || 1 = 1
    1 || 0 = 1 
    0 || 1 = 1
    0 || 0 = 0
    或的時候 只要有一個為真 那么整個結果就是真。

  • 非運算:!
    !1 = 0
    !0 = 1

  • 異或運算:
    兩個數字相同為0;
    兩個數字不相同為1;

短路預算:

命令1 && 命令2 命令1 成功執行 則執行命令2
命令1 執行失敗 則不會執行命令2

命令1 || 命令2 命令1成功執行,則命令2不執行
命令1執行失敗,則命令2執行

命令1 && 命令2 || 命令3
如果命令1 成功執行 則執行命令2 且命令3不會執行
如果命令1 執行失敗 那么命令2就不會執行,則命令3執行

如果 命令1 成功
則 命令2;
否則 命令3;

退出狀態

進程使用退出狀態來報告成功或失敗

  • 0 代表成功,1-255代表失敗
    $? 變量保存最近的命令退出狀態

[root@magedu bin]# ping -c1 -W1 hostdown &> /dev/null
[root@magedu bin]# echo $?
2

  • exit [n]:自定義退出狀態碼
    注意:腳本中一旦遇到exit命令,腳本會立即終止;終止退出狀態取決于exit命令后面的數字
    注意:如果未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決于腳本中執行的最后一條命令的狀態碼

測試條件

  • test 測試條件
    [ 測試條件 ]
    [[ 測試條件 ]] 條件測試的前后要加上空格
    生產環境建議使用兩個中括號

  • 數值測試:
    -gt: 是否大于
    -ge: 是否大于等于
    -eq: 是否等于
    -ne: 是否不等于
    -lt: 是否小于
    -le: 是否小于等于

    [root@Centos7 script]# [ 1 -gt 2 ] && echo “OK”
    [root@Centos7 script]# [ 3 -gt 2 ] && echo “OK”
    OK
    [root@Centos7 script]# 
    [root@Centos7 script]# [ 3 -ge 2 ] && echo “OK”
    OK
    [root@Centos7 script]# [ 2 -ge 2 ] && echo “OK”
    OK

  • 字符串測試:

    == 是否等于
        [[ "abs" == ??? ]] 使用通配符不加引號
        > 是否大于
        < 是否小于
        != 是否不等于
        =~ 左邊的字符串是否包含右邊指定的字符串
        -z 測試字符串是否為空
        -n 測試字符串是否不為空
        -f filename

    注:此表達式一般用于[[]]中,并且用于字符串比較時用到的操作數都應該使用引號;

    [[ -f filename ]] 應用:
    [root@Centos7 script]# [[ -f /etc/profile ]] && echo “OK” || echo “not OK”
    OK
    [root@Centos7 script]# 
    [root@Centos7 script]# [[ -f /etc/profilefdfd ]] && echo “OK” || echo “not OK”
    not OK
    [root@Centos7 script]# 
    [root@Centos7 script]# [[ -f /etc/ ]] && echo “OK” || echo “not OK”
    not OK

  • 文件測試

    • 文件存在性測試:
      -e FILE:文件存在性測試,存在為真,否則為假
      -a FILE:同-e
    • 存在性及類別測試
      -b FILE:是否存在且為塊設備文件
      -c FILE:是否存在且為字符設備文件
      -d FILE:是否存在且為目錄文件
      -f FILE:是否存在且為普通文件
      -h FILE 或 -L FILE:是否存在且為符號鏈接文件
      -p FILE:是否存在且為命名管道文件
      -S FILE:是否存在且為套接字文件

    • 文件權限測試:(針對于當前用戶)
      -r FILE:是否存在且可讀
      -w FILE:是否存在且可寫
      -x FILE:是否存在且可執行

    • 文件特殊權限測試:
      -u FILE:是否存在且擁有suid權限
      -g FILE:是否存在且擁有sgid權限
      -k FILE:是否存在且擁有sticky權限

    • 文件大小測試:
      -s FILE:是否存在且非空

    • 文件是否打開:
      -t fd:fd表示文件描述符是否已經打開且與某終端相關
      -N FILE:文件自從上一次被讀取之后是否被修改過
      -O FILE:當前有效用戶是否為文件屬主
      -G FILE:當前有效用戶是否為文件屬組

組合測試條件

  • COMMAND1 && COMMAND2 并且
    COMMAND1 || COMMAND2 或者
    ! COMMAND 非
    如:[[ -r FILE ]] && [[ -w FILE ]]

  • EXPRESSION1 -a EXPRESSION2 并且
    EXPRESSION1 -o EXPRESSION2 或者
    ! EXPRESSION 
    “!” 最高,”-a” 次之,”-o” 最低。

[]與[[]]的區別

  • [ $A == “boy” ]
    報錯:-bash:[: ==:期待一元表達式
    使用[ “$A” == “boy” ]
    或者[ X”$A” == X”boy” ] 或者 [[ “$A” == “boy” ]] ( 最佳方案)

  • [ 1 > 2 ]
    使用 [[ 1 > 2 ]]不用對大于號進行轉義

  • [[ ]]支持通配符和正則表達式
    [[ “aaa” == ??? ]]
    [[ “aaa” =~ .{3} ]] 擴展正則表達式

bash的配置文件

  • 按生效范圍劃分,存在兩類:

    • 全局配置:
      /etc/profile
      /etc/profile.d/*.sh
      /etc/bashrc
    • 個人配置:
      ~/.bash_profile
      ~/.bashrc
  • 按功能劃分,存在兩類:

    • profile類:為交互式登錄的shell提供配置

      • 全局:/etc/profile,/etc/profile.d/*.sh
      • 個人:~/.bash_profile

        功用:

      • 用于定義環境變量
      • 運行命令或腳本
    • bashrc類:為非交互式和交互式登錄的shell提供配置

      • 全局:/etc/bashrc
      • 個人: ~/.bashrc

        功用:

      • 定義命令別名和函數
      • 定義本地變量
  • shell登錄兩種方式

    • 交互式登錄:

      • 直接通過終端輸入賬號密碼登錄;
      • 使用 “su – UserName” 切換的用戶

        執行順序:

        /etc/profile –> /etc/profile.d/*.sh –> ~/.bash_profile –> ~/.bashrc

        –> /etc/bashrc

    • 非交互式登錄:

      • su UserName
      • 圖形界面下打開的終端
      • 執行腳本

        執行順序:

        ~/.bashrc –> /etc/bashrc –> /etc/profile.d/*.sh

  • 編輯配置文件生效

    • 重新啟動shell進程
    • . 或 source

bash 退出任務

  • 保存在~/.bash_logout文件中(用戶)
  • 在退出登錄shell時運行
  • 用于:創建自動備份;清除臨時文件;

語句控制

  • 過程式編程語言有三種過程:
    順序執行:按照順序一條一條語句執行
    選擇執行:按照條件進行選擇執行
    循環執行:按照給定的循環條件進行循環執行
    其中順序執行不需要特定的控制,只需要按照語句依次執行即可;選擇執行,則需要特定的語句(if、case)來判斷選擇執行;
    循環執行則需要特定的循環控制體來控制(for、while、until)

  • read
    -p 指定要顯示的提示
    -s 靜默輸入,不顯示輸入的字符
    -n N指定輸入的字符長度N
    -d ‘字符’輸入結束符
    -t N TIMEOUT為N秒
    read 從標準輸入中讀取值,給每個單詞分配一個變量,所有剩余單詞都被分配給最后一個變量
    read -p “Enter a filename : ” FILE

  • 選擇執行

    • if
  • 循環執行(for、while、until)
    循環就是程序按照一定的條件反復進行執行相關操作,直到不再滿足循環條件時結束;

    • for、while:當型循環,條件為真時循環,條件為假時退出;
      until :直到型循環,條件為假時循環,條件為真時退出;

    • 3種循環比較,循環主要有2種結構

    • Shell腳本編程

      從上面流程圖,顯然可以看出while循環是”當型的”,until循環是”直到的”

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

(0)
ss
上一篇 2017-04-13
下一篇 2017-04-14

相關推薦

  • 正則表達式

    1、用正則表達式表示IP地址 擴展正表達式表示的: (\<([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])\> 2、用正則表達式表示手機號 "^1[3578…

    Linux干貨 2016-08-07
  • 初學Linux之用戶、組和權限

    1、用戶和組管理命令 ?
    2、理解文件權限和默認權限 ?
    3、設置文件權限
    4、特殊權限 ?
    5、ACL

    2017-12-08
  • 第二周-博客

    本文大綱 文件系統層級結構標準 Linux上常見的文件類型 bash的基礎特性 用戶、組和普通權限 一些零散命令的使用 文件系統層級結構標準 FHS是Filesystem Hierarchy Standard(文件系統層次化標準)的縮寫,多數Linux版本采用這種文件組織形式,類似于Windows操作系統中c盤的文件目錄,FHS采用樹形結構組織文件。FHS定…

    Linux干貨 2016-12-07
  • 馬哥教育網絡班19期+第八周課程練習

    1、請描述網橋、集線器、二層交換機、三層交換機、路由器的功能、使用場景與區別。    主要功能:    網橋是一個局域網與另一個局域網之間建立連接的橋梁,屬于數據鏈路層的一種設備。    集線器是可以將一些機器連接起來組成一個局域網的設備。   &n…

    Linux干貨 2016-06-26
  • 搭建博客程序wordpress

    根據需求安裝相關軟件,搭建實驗環境: #CentOS 6:Httpd,PHP,mysql-server,php-mysql #CentOS 7:Httpd,php,php-mysql mariadb-server 下載wordpress程序,并解壓至/var/www/html/目錄下 [root@centos077 html]# pwd /var/www/h…

    2017-04-28
  • Linux系統上命令的使用格式

    第一部分:Linux系統上命令的使用格式 命令的語法通用格式:      COMMAND OPTIONS ARGUMENTS     發起一個命令:請求內核將某個二進制程序運行為一個進程;      程序 —-> 進程   &nbs…

    Linux干貨 2016-08-15

評論列表(2條)

  • renjin
    renjin 2017-04-21 11:07

    主要介紹了bash編程的變量,循環語句,判斷語句,內容寫的很不詳細,排版也非常好,繼續努力 !

  • Lakeisha
    Lakeisha 2017-04-24 05:25

    16Mi6rion,Exastem muitas marcas s????rias, mas todos os dias surgem pedidos de ‘vamos fazer um post em troca de um bloquinho?’ e coisas do tipo.N???£o sei como tem gente que cai nessas.Concordo contigo q t???? faltando uma boa dose de respeito!Beijo grande,

欧美性久久久久