第七章,shell編程基礎

更多筆記點擊查看

Linux學習從入門到打死也不放棄,完全筆記整理(持續更新)

https://blog.51cto.com/13683480/2095439


筆記整理開始時間:2018年4月12日11:37:35

 

本章內容:

        編程基礎

        腳本基本格式

        變量

        運算

        條件測試

        配置用戶環境

        

編程基礎:

        程序:指令+數據

        程序編程風格:

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

                      面向過程就是分析出解決問題所需要的步驟,然後用函數把這些步驟

                      一步一步實現,使用的時候一個一個依次調用就可以了

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

                      面向對象是把構成問題事務分解成各個對象,建立對象的目的不是爲

                      了完成一個步驟,而是爲了描敘某個事物在整個解決問題的步驟中的行爲

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

                        是對一堆Linux命令的邏輯化處理

        

        程序的的執行方法:

               計算機:運行二進制指令

               編程語言:

                     低級:彙編

                     高級:

                            編譯:高級語言-->編譯器-->目標代碼

                                    在編譯時將代碼轉換成2進制

                                    java,c#

                            解釋:高級語言-->解釋器-->機器代碼

                                    在程序執行時才轉換成2進制

                                    shell,perl,python

        編程基本概念:

               編程邏輯處理方式

                     順序執行,循環執行,選擇執行

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

                     編程語言的基本結構:

                             各種系統命令的組合

                             數據存儲:變量、數組

                            表達式:a + b

                            語句:if

        

shell腳本基礎:

        shell腳本:

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

        格式要求:首行shebang機制

               #!/bin/bash                          shell

               #!/usr/bin/python        python

               #!/usr/bin/perl                    perl

        shell腳本的用途有:

               自動化常用命令

               執行系統管理和故障排除

               創建簡單的應用程序

               處理文本或文件

 

創建shell腳本:

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

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

                     #!/bin/bash

               添加註釋

                     註釋以#開頭

        第二步:運行腳本

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

                      /root/hello

               直接運行解釋器(bash),如:

                     bash  /root/hello

                     cat ff115  |bash

        PS:source 執行程序  表示腳本會在當前shell運行不開啓子進程

 

腳本規範:

        1.第一行一般爲調用使用的語言

        2.程序名,避免更改文件名爲無法,正確找到的文件

               (如不要取名bash,或者其他存在的程序名)

        3.版本號

        4.更改後的時間

        5.作者相關信息

        6.該程序的作用。以及注意事項

        7.最後是各版本的更新簡要說明

 

腳本基本結構

        #!shebang

        configuration_variables        配置變量

        function_definitions              定義函數

        main code                                  主要代碼

        

腳本調試:

        檢測腳本中的語法錯誤

               bash -n hello.world

               如:

                     [root@sentos7 ~/bin]#bash -n ceshi

                     ceshi: line 2: unexpected  EOF while looking for matching `"'

                     ceshi: line 7: syntax  error: unexpected end of file

        調試執行:

               bash -x hello.world

        PS:

               bash -n 只檢查語法錯誤

               如果是語法錯誤後續命令不執行

               如果是命令not found 後續會繼續執行

               bash -x  +代表深度,直接執行+,被調用執行++

               腳本內不支持別名,也無法添加別名

               

變量:命名的內存空間

        數據存儲方式:

               把程序中準備使用的數據賦給一個簡短、易於記憶的名字

        類型:

               字符型

               數值:×××,浮點型

        作用:

               數據存儲

               參與運算

               表示數據範圍

        強類型:

               變量不經過強制轉換,它永遠是這個數據類型,不允許隱式的類型轉化。一般

               定義變量時必須指定類型,參與運算必須符合類型要求;調用未聲明變量會

               產生錯誤。

                     如jave c#

        弱類型:

               語言的運行時會隱式做數據類型轉換。無須指定類型,默認均爲字符型,參

               與運算會自動進行隱式類型轉換,變量無須事先定義可直接調用

                     如:bash不支持浮點數, php

        變量命名法則:

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

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

               3.見名知義

               4.統一命名規則:駝峯命名法

 

bash中變量的種類:

        根據變量的生效範圍等標準等標準劃分下面變量類型:

               局部變量:

                     生效範圍爲當前shell進程;對當前shell之外的其他shell進程,

                     包括當前shell的子shell進程均無效

               環境(全局)變量:

                     生效範圍爲當前shell進程及其子進程

               本地變量:生效範圍爲當前shell進程中某代碼片段,通常指函數

               位置變量:$1,$2,..${10}..來表示,用於讓腳本在腳本代碼中調用通過命令行傳遞

                     給它的參數

               特殊變量:

                     $?,$0,$*,$@,$#,$$

                     $?           前一個命令的退出狀態,成功爲0,不成功爲非0

        

局部變量:     

        變量賦值:name='value'

               可以使用引用value:

                     1.可以是直接字串;     name=‘root’

                     2.變量引用:         name=$USER

                     3.命令引用:         name=`command`

                                                         name=$(cmd)

               ps:

                      變量一旦賦值,除非重新賦值,否則所佔內存空間不變,值不變

                             name1=name2的情況

                                    就算賦值之後name2的值改變了,name1的值保持不變

                    

                     i=100      賦值爲字符,不問數字類型

        

        變量引用:

                     ${name}  $name

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

                            [root@sentos7  ~/bin]#echo "$PS1"

                            \[\e[1;35m\][\u@\h \w]\$\[\e[0m\]

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

                            [root@sentos7  ~/bin]#echo '$PS1'

                             $PS1

               

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

        刪除變量:     unset name

        PS:

               pstree -p        進程tree

               echo $$  當前進程的進程編號

               echo $PPID 父進程的進程編號

        

練習1

    1、編寫腳本/root/bin/systeminfo.sh,顯示當前主機系統信息,包括主機名,

        IPv4地址,操作系統版本,內核版本,CPU型號,內存大小,硬盤大小

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

        /root/etcYYYY-mm-dd中

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

    4、編寫腳本/root/bin/links.sh,顯示正連接本主機的每個遠程主機的IPv4地址

        和連接數,並按連接數從大到小排序

 

環境變量:

        變量聲明,賦值:

               export name=Value             相當於name=Value;export  name

               declare -x name2=Value

                     let  c=name+name2;export c

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

        顯示所有環境變量:

               env

               printenv

               export

               declare -x

        刪除變量:

               unset name

        bash內建的環境變量:

               PATH:    

               SHELL:

               USER:

               UID:

               HOME:

               PWD:

               SHLVL:          當前shell層數

               LANG:            語言鍵盤、字符編碼

               MAIL:           當前用戶mail目錄

               HOSTNAME:

               HISTSIZE:

               _:                    前一個命令的最後一個參數

               

只讀和位置變量:

        只讀變量:只能聲明,但不能修改和刪除

               聲明只讀變量:

                     readonly  name

                     declare -r  name

               查看只讀變量:

                     readonly  -p

        

        位置變量:再腳本代碼中調用通過命令行傳遞給腳本的參數

               $1,$2,..${10}..:   對應相應第1,2..10..個參數

                     腳本中命令:shift[n] 可以傳遞參數位置,如:

                            shift              可以將原本$2,變成$1

                            shift 3            將原$4變成$1

               $0    命令本身,名字

                     默認帶路徑,可以用 `basename $0`取出來

               $0  如果是軟鏈接的話 $0會顯示各自軟鏈接的名字

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

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

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

                     $@ $*    在腳本調用腳本傳遞參數時,如果用"$*",會將所有參數當成一個

                                           字符串傳遞

                                   $* $@  "$@"   會將每個參數單獨傳遞

        set --     清空所有位置變量

        

退出狀態

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

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

                     0            成功

                     1-255     失敗

        例如:     

               ping -c1 172.20.3.14 &>/dev/null

               echo $?

        

        退出狀態碼:

               bash 自定義退出狀態碼

               exit [n]    自定義退出狀態碼

               注意:

                     腳本中一旦遇到exit命令,腳本會立即終止;終止退出狀態取決於

               exit命令後面的數字

                      如果沒有給腳本指定退出狀態碼,整個腳本的退出狀態碼取決於腳本

               中執行的最後一條命令的狀態碼

        

算術運算:let

        

        bash中的算術運算:help let

        常用算術:

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

        實現算術運算的格式:

               1.     let var=算術表達式

                            let  z=x+y;let x++;let  y=x**2;

                            let  z=(3*x+4*y/3)-2*x

               2.     var=$[算術表達式]

                             z=$[(3*x+4*y/3)-2*x]

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

                             z=$(((3*x+4*y/3)-2*x))

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

                            如:z=$(expr $x + $y)         表示z=x+y

                     *需要寫成\*

               5.     declare -i  var=數值(可以使是算式)

                            declare -i  x=x+y

                            declare -i  x=3*x+y*4/2

               6.     echo ’算術表達式‘ |bc

 

        bash有內建的隨即數生成器:$RANDOM(0-32676)

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

        

賦值:

        增強型賦值:

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

               let x+=3;x-=1;x*=5;x/=4           

                            +3 -1  *5     /4

                      shell不支持浮點計算,所以除法會有商整取餘

        自增,自減

               let x+=1;let x++

               let x-=1;let x--

               

練習2      

        1、編寫腳本/root/bin/sumid.sh,計算/etc/passwd文件中的第10個用戶和第

        20用戶的ID之和

     2、編寫腳本/root/bin/sumspace.sh,傳遞兩個文件路徑作爲參數給腳本,計

        算這兩個文件中所有空白行之和

     3、編寫腳本/root/bin/sumfile.sh,統計/etc, /var, /usr目錄中共有多少個一級

        子目錄和文件

 

 

邏輯運算

        與:        &

        或:        |              

        非:        !

               !1=0

               !0=1

        短路運算:

               cmd1 && cmd2

               如果cmd1爲假,cmd2不需要執行,反之cmd1爲真,需要cmd2執行

 

               cmd1 || cmd2

               如果cmd1爲真,cmd2不需要執行,反之cmd1爲假,需要cmd2執行

 

               cmd1 && cmd2 || cmd3    要求cmd2必真

                     cmd1爲真,執行cmd2

                            爲假,執行cmd3

        異或:^ XOR

               二進制運算,同爲0 異爲1

               a=5;b=6;echo $a  $b;a=$[a^b];b=$[a^b];a=$[a^b];echo $a $b       

                     將a  b的值互換

ture 和false

        只返回真或者假,不做任何操作

        true && echo hello

     false   && echo hello||echo nihao

        

條件測試:test

        

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

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

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

               若真        則返回0

               若假        則返回1

        測試命令:

               test expression              如:test a = b ;echo  $?

               [ $a = b ] && echo ture || echo  false

              [[ $a =~ pattern ]]

        表達式epression 前後必須有空白字符

        

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

               && 代表條件性的and then

               ||      代表條件性的 or else

        例如:

               grep -q no_such_user /etc/passwd || echo 'NO such  user'

               id usera &>/dev/null && echo "usera is exist" || useradd  usera

               

        長格式的例子:

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

                     [ "$A" == "$B" ]

               test "$A" -eq "$B" && echo "Integers are  equal"

                     [ "$A" -eq "$B" ]

        

bash的數值測試:

        -v var

               變量是否設置 test -v var && echo hello||echo  nihao

               [ -v var ] && set || not  set

        PS:

               此處使用變量var前不可加"$",否則判斷異常

                             

               

        數值測試:

               -gt 是否大於              [ $A -gt $B  ]

               -ge        是否大於等於

               -eq         是否等於

               -ne        是否不等於

               -lt           是否小於

               -le          是否小於等於

               

bash的字符串測試:

        

               ==          是否等於                                    等於爲真,0

               >            ascii碼是否大於ascii碼     

               <                           是否小於

               !=            是否不等於                                 不等於爲真,0

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

               注意:此表達式一般用於[[ ]]中,支持擴展的正則表達式

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

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

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

                     [[ ]]使用pattern時 表達式 不能加引號 ,也不能識別\< \>  \b

                    判斷是否爲空也可以:

                            [ x = x"$a" ] && echo ture || echo false

        

練習3:

        1、編寫腳本/root/bin/argsnum.sh,接受一個文件路徑作爲參數;如果參數

        個數小於1,則提示用戶“至少應該給一個參數”,並立即退出;如果參數個數

        不小於1,則顯示第一個參數所指向的文件中的空白行數

 2、編寫腳本/root/bin/hostping.sh,接受一個主機的IPv4地址做爲參數,測

        試是否可連通。如果能ping通,則提示用戶“該IP地址可訪問”;如果不可

        ping通,則提示用戶“該IP地址不可訪問”

 3、編寫腳本/root/bin/checkdisk.sh,檢查磁盤分區空間和inode使用率,如

        果超過80%,就發廣播警告空間將滿

        

Bash的文件測試:

        存在性測試:

               -a file            同  -e

               -e file             文件存在性測試,存在爲真,否則爲假

        存在性及類別測試

               -b file             是否存在且爲塊設備文件

               -c file              是否存在且爲字符設備文件

               -d file             是否存在且爲目錄文件

               -f file              是否存在且爲普通文件

               -h file     或 -L file        是否存在且爲符號鏈接文件

               -p file    是否存在且爲命名管道文件

               -S file             是否存在且爲套接字文件

               

Bash的文件權限測試:

        文件權限測試:

               -r file              是否存在且可讀

               -w file             是否存在且可寫

               -x file     是否存在且可執行

        文件特殊權限測試:

               -u file             是否存在且擁有suid權限

               -g file             是否存在且擁有sgid權限

               -k file     是否存在且擁有sticky權限

        

Bash的文件屬性測試:

        文件大小測試:

               -s file              是否存在且爲空

        文件是否打開

               -t fd:fd 文件描述符是否在某終端已經打開

               -N file             文件自從上一次被讀取之後是否被修改過

               -O file             當前用戶是否爲文件屬主

               -G file             當前有效用戶是否爲文件屬組

        雙目測試:

               file1 -ef file2          file1是否是file2的硬鏈接

               file1 -nt file2 file1是否新於file2  (mtime)

               file1 -ot file2         file1是否舊與file2

        

Bash的組合測試條件:

        第一種方式:

               cmd1 && cmd2    且

               cmd1 ||   cmd2      或

               !cmd                  非

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

        第二種方式:

               [ expression1 -a expression2 ]            並且

               [ expression1 -o expression2 ]            或者

               [ !expression ]                                非

        例:

               [ -z "$HOSTNAME" -o "$HOSTNAME" == "localhost.localdomain" ] &&

                     hostname www.magedu.com  

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

        

        PS:

               &&(-a)     ||(-o)可連續使用

               

               [ -r "$1" -a -w "$1" -a -x "$1" ]  && echo ture ||  false

                     [ -a "$1"  ] && [ -r "$1" ] && [ -w "$1" ] && [ -x "$1" ]  && echo ture || false

                     只要有一個爲假,就返回假

               [ -r "$1" -o -w "$1” -o "$1" ] && echo  ture || false

                     [ -r "$1"  ] || [ -w "$1" ] || [ -x "$1"] && echo ture ||  false

                     只要一個爲真,則返回爲真

練習:

        1、編寫腳本/bin/per.sh,判斷當前用戶對指定參數文件,是否不可讀並且不可寫

    2、編寫腳本/root/bin/excute.sh ,判斷參數文件是否爲sh後綴的普通文件,如

        果是,添加所有人可執行權限,否則提示用戶非腳本文件

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

        

read:

        使用read來把輸入值分配給一個或多個shell變量

               -p                  指定要顯示的提示,如:

                                   read -p  "Please input your name: " name

               -s                  靜默輸入,一般用於密碼,如:

                                   read -s -p  "Please input your password: " passw

               -n N               指定輸入的字符長度N

                                    指定長度之後,如達到長度,後續指令不會換行,直接在輸入的內容之後顯示了

                                    想要達到換行的目的,需要下一行加上

                                          echo  ""   但是如果手動回車則會顯示一行空行

               -d '字符' 輸入結束符     到此字符直接結束輸入

                                   read -t 20 -n  20 -p "Please input you ID, end with'#' : "  ID

                                   與-n類似,也是不會換行

               -t N        TIMEOUT爲N秒

                                    timeout並不會退出腳本,而是會執行後續指令

        

        read        如果從標準輸入中讀取值,給每個單詞分配一個變量

                      所有剩餘單詞都被分配給最後一個變量

               不支持管道接受標準輸入     | read name

 

bash如何展開命令行

               把命令行分成單個命令詞

               展開別名

               展開大括號的聲明({})

               展開波浪符聲明(~)

               命令替換$()和(``)

               再次吧命令行分成命令詞

               展開文件通配(*、?、[abc]等等)

               準備I/O重導向(<,>)

               運行命令

 

防止擴展:

        反斜線 \ 會使隨後的字符按原意解釋

               $     echo your cost:\$5.00

               your cost:$5.00

        加引號來防止擴展

               單引號''   防止所有擴展

               雙引號"" 也防止所有擴展,但是以下情況例外

                     $                   --變量擴展

                     `` $()        --命令替換

                     \                    --禁止單個字符擴展

                     !                   --歷史命令替換

 

bash的配置文件:

        按生效範圍劃分、存在兩類

        全局配置:

               /etc/profile

               /etc/profile.d/*.sh

               /etc/bashrc

        個人配置:

               ~/.bash_profile

               ~/.bashrc

 

shell登錄兩種方式

        交互式登錄:

               1)直接通過終端輸入賬號密碼登錄

               2)使用 su - username 切換的用戶

               執行順序:

                     /etc/profile -->  /etc/profile.d/*.sh --> ~/.bash_profile -->

               ~/.bashrc -->  /etc/bashrc

        非交互式登錄:

               1)su username

               2)圖形界面下打開的終端

               3)執行腳本

               4)任何其他的bash實例

               執行順序:~/.bashrc -->  /etc/bashrc --> /etc/profile.d/*.sh

               

按功能劃分:

        profile類:

               爲交互式登錄的shell提供配置

               全局:/etc/profile,  /etc/profile.d/*.sh

               個人:~/.bash_profile

               功能:

                     用於定義環境變量

                     運行命令或腳本

        

        bashrc類:

               爲交互式和非交互式登錄的shell提供配置

               全局:/etc/bashrc

               個人:~/.bashrc

               功能:

                     定義命令別名和函數

                     定義本地變量

        

配置文件修改生效:

        修改profile和bashrc文件後需生效

               兩種方法:

                     重新啓動shell進程(重新登錄)

                     . 或  source

                     例如:  . ~/.bashrc

 

Bash退出任務:

        保存在~/.bash_logout文件中

        在退出登錄shell時運行

        用於:

               創建自動備份

               清楚臨時文件

               

變量:$-

        h:hashall,打開這個選項後,shell

        會將命令所在的路徑hash下來,避免每次都要查詢。通過set+h將h選項關閉

        

        i:interactive-comments,包含這個選項說明當前的shell是一個交互式的shell

        所謂的交互式shell,在腳本中,i選項都是關閉的

        

        m:monitor,打開監控模式,就可以通過job  control來控制進程的停止、繼續、

        後臺或者前臺執行等。

        

        B:braceexpand,大括號擴展

        

        H:history,H選項打開,可以展開歷史列表中的命令,可以通過!來完成,

               例如!!,返回最近的一個歷史命令,!n  返回第n個歷史命令

               

練習:

        1、讓所有用戶的PATH環境變量的值多出一個路徑,例如:

        /usr/local/apache/bin

    2、用戶root登錄時,將命令指示符變成紅色,並自動啓用如下別名:

        rm=‘rm –i’

        cdnet=‘cd  /etc/sysconfig/network-scripts/’

        editnet=‘vim  /etc/sysconfig/network-scripts/ifcfg-eth0’

        editnet=‘vim /etc/sysconfig/network-scripts/ifcfg-eno16777736  或 ifcfg-ens33 ’ (如果系

        統是CentOS7)

    3、任意用戶登錄系統時,顯示紅色字體的警示提醒信息“Hi,dangerous!”

    4、編寫生成腳本基本格式的腳本,包括作者,聯繫方式,版本,時間,描述等

    5、編寫用戶的環境初始化腳本reset.sh,包括別名,登錄提示符,vim的設置,

環境變量等

        

        

筆記整理完成時間:2018年4月13日16:58:39     

        

        

 


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