基礎shell的簡介


      shell腳本是Linux運維工程師必須掌握的技能之一,shell腳本的使用讓我們更好的操作Linux系統,方便了我們的執行。


一,編程基礎

編程基本概念

編程邏輯處理方式:順序執行,循環執行,選擇執行

程序:指令+ 數據

shell 編程:過程式、解釋執行

shell程序:提供了編程能力,解釋執行

程序編程風格:

     過程式:以指令爲中心,數據服務於指令

     對象式:以數據爲中心,指令服務於數據

程序的執行方式

     計算機:運行二進制指令;

編程語言的基本結構:

      數據存儲:變量、數組

      表達式: a + b

      語句:if

編程語言:

     低級:彙編

     高級:

         編譯:高級語言--> 編譯器--> 目標代碼  : java,C#

         解釋:高級語言--> 解釋器--> 機器代碼  : shell, perl, python

編程程序語言分類

強類型:定義變量時必須指定類型、參與運算必須符合類型要求;調用未聲明變量會產生錯誤

如 java,python

弱類型:無須指定類型,默認均爲字符型;參與運算會自動進行隱式類型轉換;變量無須事先定義可直接調用

如:bash  不支持浮點數


二,shell 腳本基礎

shell腳本規範和用途:

shell 腳本是包含一些命令或聲明,並符合一定格式的文本文件

格式要求:首行shebang 機制

      shell腳本:#!/bin/bash; 文件名以 .sh 結尾

      Python: #!/usr/bin/python; 文件名以 .py 結尾

      Perl   :#!/usr/bin/perl ; 文件名以 .pl 結尾

shell 腳本的用途有:

      自動化常用命令

      執行系統管理和故障排除

      創建簡單的應用程序

      處理文本或文件


創建shell 腳本

第一步:使用文本編輯器來創建文本文件

      第一行必須包括shell 聲明序列:#!: #!/bin/bash

      添加註釋:註釋以# 開頭

第二步:運行腳本

      給予執行權限,在命令行上指定腳本的絕對或相對路徑

      直接運行解釋器,將腳本作爲解釋器程序的參數運行


腳本調試

bash -n /path/to/some_script

檢測腳本中的語法錯誤

bash -x /path/to/some_script

調試執行


三,腳本變量的基礎

變量(變量的內容是可以更改的,它可以存儲很多類型的數據)

變量:命名的內存空間

     數據存儲方式:

            字符:

            數值:整型,浮點型

變量:變量類型

     作用:1 、數據存儲格式;2 、參與的運算;3 、表示的數據範圍

     類型:

           字符

           數值:整型、浮點型

變量命名法則:

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

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

     3 、見名知 義

     4 、統一命名規則:駝峯命名法(多個單詞命名,分爲大,小駝峯,大駝峯是每個單詞的第一個字母大寫,小駝峯是除了第一個單詞小寫其他單詞的第一個字母大寫)

{

sleep 休眠:在腳本中執行 sleep + 時間 可以有時間查看父子進程,sleep默認時間爲秒。

定義變量時不能帶空格,必須用雙引號擴起來纔可以。

echo默認是一行,加雙引號就可以原原本本顯示出來。

}



四,變量的範圍簡介

根據變量的生效範圍等標準:

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

      變量賦值:name=‘value’

      可以使用引用value:

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

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

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

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

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

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

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

      刪除變量:unset name


環境變量:生效範圍爲當前shell 進程及其子進程局部變量:生效範圍爲當前shell 進程中某代碼片斷( 通常指函數)

      變量聲明、賦值:

          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


只讀變量:只能聲時,但不能修改和刪除(一般使用在常量身上)

      readonly name

      declare -r name

(declare -rx name  定義一個即使常量,也是環境變量)


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

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

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

       $0:  命令本身

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

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

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

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

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

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

             echo "$1 has $linecount lines."

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

      basename  + 文件名

      basename的語法是:basename[選項][參數]

              選項:爲有路徑信息的文件名,如/home/test/test.txt

              參數:指文件擴展名



五,bash運算

算術運算:help let(bash雖然不支持浮點,但是還是支持加減乘除的)

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

         實現算術運算:

               (1) let var= 算術表達式

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

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

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

               (5) declare –i var =  數值  (需要先申明數值,在進行計算)

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

         乘法符號有些場景中需要轉義 ,如 如*

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

         echo $[$RANDOM%50]  :0-49

(echo $[RANDOM%50+1] :1-50    %50+1 :是0-49整體性的+1,不是單個的49+1)

         $?是查看上一個命令的狀態,

         expr使用乘號需要把乘號轉義和加空格  如:expr 2 \* 3

賦值

         增強型賦值:+=, -=, *=, /=, %=

{

% : 在算術運算中,這個是求模操作符,即兩個數進行除法運算後的餘數;

}

         let varOPERvalue

              例如:let count+=3(自己先加3 後再給自己賦值)

         自增,自減:

              let var+=1

              let var++

              let var-=1

              let var--


邏輯運算

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 ,結果必定爲0;

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

          cmd1 && cmd2

          cmd1 成功,將執行cmd2

          cmd1 失敗,將不執行cmd2

     短路或 :(||)

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

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

          cmd1 成功,將不執行cmd2

          cmd1 失敗,將執行cmd2

     異或:^

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

{

短路與  和   普通與 的區別

cmd1 &&  cmd2

短路與:  cmd1 爲真時  ,執行 cmd2 ;  cmd1爲假時  ,不執行 cmd2  直接退出。

普通與: cmd1 不管是真是假,cmd2 都要執行 。

短路或  和   普通或 的區別

cmd1 || cmd2

短路與 : cmd1 爲真時,可以不用執行 cmd2 直接退出; cmd1 爲假時,執行 cmd2 。

普通與 : cmd1 不管是真是假,cmd2 都要執行。

}


六,bash的退出狀態

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

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

      $?  變量保存最近的命令退出狀態(最後一條的命令的狀態)

例如:

      $ ping -c1 -W1 hostdown &> /dev/null

      $ echo $?

(ping  -c1  代表拼一個)(ping -W1    一秒,默認爲是五秒,在局域網一般最多需要一秒連接的顯示信息就能返回,在互聯網時間稍長一點)


退出狀態碼

bash 自定義退出狀態碼

exit [n] :自定義退出狀態碼;(在腳本中(exit)執行的是子shell )

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

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


七,bash 的測試類型

條件測試

判斷某需求是否滿足,需要由測試機制來實現;

專用的測試表達式需要由測試命令輔助完成測試過程;

評估布爾聲明,以便用在條件性執行中

      若真,則返回0

      若假,則返回1

測試命令:

      test EXPRESSION   (test $a = $b    測試$a 和$b 是否相同時 $a 和$b的前後必須要有空格,要是沒有就成了賦值了)

      [ EXPRESSION ]

      ` EXPRESSION `    ([[ $a ]] 測試$a 是否定義過值)

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

test 命令

     長格式的例子:

          $ test "$A" == "$B" && echo "Strings are equal"

          $ test “$A” -eq “$B” \

          && echo "Integers are equal"

     簡寫格式的例子:

           $ [ "$A" == "$B" ] && echo "Strings are equal"

           $ [ "$A" -eq "$B" ] && echo "Integers are equal"

條件性的執行操作符

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

      &&  代表條件性的AND THEN

      || 代表條件性的OR ELSE

例如:

      $ grep -q no_such_user /etc/passwd \|| echo 'No such user'

      No such user

      $ ping -c1 -W2 station1 &> /dev/null \> && echo "station1 is up" \> || (echo 'station1 is unreachable'; exit 1)

      station1 is up


數值測試:

     -gt:  是否大於;

     -ge:  是否大於等於;

     -eq:  是否等於;

     -ne:  是否不等於;

     -lt:  是否小於;

     -le:  是否小於等於;


字符串測試:

     == :是否等於;

     >: ascii 碼是否大於ascii碼

     <:  是否小於

     !=:  是否不等於

     =~:  左側字符串是否能夠被右側的PATTERN所匹配(右側是要使用擴展正則表達式)

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

{

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

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

      注意:  此表達式一般用於` ` 中;

}


文件測試

     存在性測試

          -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;

}(比的是文件的修改時間)


組合測試條件

      第一種方式:

            COMMAND1 && COMMAND2  並且

            COMMAND1 || COMMAND2  或者

            ! COMMAND 非

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

      第二種方式:

            EXPRESSION1 -a EXPRESSION2  並且

            EXPRESSION1 -o EXPRESSION2  或者(or)

            ! EXPRESSION

            必須使用測試命令進行;

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

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



八,聚集命令

有兩種聚集命令的方法:

複合式:date; who | wc -l (命令會一個接一個地運行)

子shell :(date; who | wc -l ) >>/tmp/trace  (所有的輸出都被髮送給單個STDOUT 和STDERR)



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章