關於shell腳本編程第一篇

                                              shell腳本編程(1)
腳本的基本格式:
              程序:指令+數據
程序編程風格分爲兩種:
                    過程式:以指令爲中心,數據服務於指令
                    對象式:以數據爲中心,指令服務於數據
過程式編程有以下幾個特點:
                        順序執行
                        循環執行
                        選擇執行
shell編程:
          過程式、解釋執行
          編程語言的基本結構
          數據存儲:變量、組數
          表達式:a+b
          語句: if                       
shell程序:是一個過程式的解釋器,提供了編程能力,解釋執行
程序的執行過程:先把源碼程序翻譯成機器語言(生成可執行的文件),然後解釋執行。
對於過程式編程而言,把一行源碼程序翻譯成機器語言,然後執行,在翻譯下一行的源碼程序爲機器語言,然後再次執行
對於計算機,只能識別的是二進制文件

編程語言:
       低級:
           彙編語言
       高級:
           編譯過程:高級語言>編譯器>目標代碼 如:java ,C         
           解釋過程:高級語言>解釋器>機器代碼 如: shell,perl,python
          
shell 腳本其實就是以一系列命令組合起來的文本文件,這些命令組合起來完成一個或者一項功能。
 也可以這樣理解 shell腳本是包含好一些命令或聲明,並符合一定格式的文本文件           
格式要求:shell程序開頭的環境指定,我們稱之爲shebang機制
        #!/bin/bash
        #!/usr/bin/python
        #!/usr/bin/perl
        各種命令組合在一起,形成一個腳本

shell腳本的用途有:
                 自動化常用命令
                 執行系統管理和故障排除
                 創建簡單的應用程序
                 處理文本或文件
    
創建shell腳本:
             使用編輯器來創建文本文件
             第一行必須包括shell聲明序列:#!  #!/bin/bash
             添加註釋信息 以#開頭    
    
運行腳本:
        給予執行權限,通過具體的文件路徑制定文件執行
        直接運行解釋器,將腳本作爲解釋器程序的參數運行
腳本調式:
        bash -n /path/to/some_script     檢查腳本中是否語法錯誤
        bash -x /path/to/some_script     調試執行
      

 
shell腳本格式示例
#!/bin/bash/        開頭格式
#                   註釋信息
# Author: root     
# date: 20160812-08:12:08
# Vervion: 0.0.1
# Description:
# Synopsis:
   echo "信息內容"

關於變量:
         什麼是變量:命名的內存空間
                     數據存儲方式
變量作用類型:
            作用:
                數據存儲格式
                參與運算
                表示的數據範圍
            類型 :
                 字符
                 數值: 整型,浮點型
                    
     
變量類型分爲兩類:
強類型:定義變量是必須指定類型、參與運算必須符合類型要求;調用未聲明變量會產生錯誤
弱類型:無需指定類型,默認均爲字符型;參與運算會自動進行隱式類型轉換;變量無須是想定義可直接調用

變量命名法則:
            不能使用程序中的保留字:例如if,for等
            只能使用數字、字母及下劃線,且不能以數字開頭
            要做到看到變量名稱就知道是什麼意思;見名知意
            統一命名法則:駝峯命名法  
            大駝峯:兩個單詞開頭字母爲大寫
            小駝峯:兩個單詞,第一個開頭爲小寫,第二個開頭爲大寫
bash中變量的種類:
根據變量的生效範圍等標準可分爲:  
                              本地變量:生效範圍爲當前shell進程;對當前shell之外的其他shell進程包括當前shell的子shell進程均無效;簡單來說,本地變量,只能對本地使用
                              環境變量:生肖範圍爲當前shell進程以及子進程。
                              局部變量:生效範圍爲當前shelll進程中某代碼片段(通常指的是函數)
                              位置變量:$1,$2,$3,....表示,用於讓腳本在腳本代碼中調用通過命令行傳遞給它的參數
                              特殊變量:
                                       $?  上個命令是否執行成功
                                       $0  表示命令本身
                                       $#  傳遞給腳本參數的個數
                                       $*  傳遞給腳本的所有參數
                                       $@  引用傳遞給腳本的所有參數
                                       pstree   查看樹形結構的進程       

本地變量:
         變量賦值: name='value' (值) 值可以引用        
                  1  可以是直接字符串 例如 name="root"
                  2  變量引用   例如 name="$username"
                  3  命令引用   例如 name=`命令`,name=$(命令)
         變量引用:$name,${name}
                  "" 弱引用,其中的變量引用會被替換成變量值
                  '' 強引用, 其中的便碧昂引用不會被替換變量值,而且保持原字符串
                  顯示已經定義的所有變量:set
                  銷燬變量:unset namme

練習
1編寫腳本/root/bin/systeminfo.sh,顯示當前主機系統信息,包括主機名,IPV4地址操作系統版本,內核本本,CPU型號,內存大小,硬盤大小
~]# vim systeminfo.sh
#!/bin/bash
#
ip=`ifconfig | grep 'inet\>' | grep -v '127.0.0.1' | tr -s ' ' | cut -d' ' -f3`
cpu=`lscpu | grep -i "model name:"`
neicun=`free -h |sed -n '2p' |tr -s ' ' | cut -d' ' -f2`
cipan=`fdisk -l | sed -n '2p' | sed -r 's/.*[[:space:]]([0-]9.*M).*/\1/g'`
echo 'hostname:'`hostname`
echo 'hostip:'$ip
echo 'OS version:'`cat /etc/redhat-release`
echo 'neihe:'`uname -r`
echo 'cpu:'$cpu
echo 'neicun:'$neicun
echo 'cipan:'$cipan
保存退出,chmod +x systeminfo.sh 加上執行權限,可直接運行


2編寫腳本/root/bin/backup.sh,可實現將/etc/目錄備份到/root/etcYYYY-mm-dd中
~]# vim backup.sh
#!/bin/bash
backdir="/root/etc$(date +%F)"
cp -a /etc/. $backdir && echo "comon $backdir stop."
保存退出,chmod +x backup.sh 加上執行權限可直接運行

3 編寫腳本/root/bin/disk.sh,顯示當前硬盤分區 中空間利用最大的值
#!/bin/bash
#
cipanname=`df |grep '/dev/sd' | tr -s ' '|sort -nr -t' ' -k5|cut -d' ' -f1`
shiyonglv=`df |grep '/dev/sd' | tr -s ' '|sort -nr -t' ' -k5|cut -d' ' -f5`
echo $cipanname
echo $shiyonglv
保存退出,chmod +x disk.sh 加上執行權限可直接運行


4 編寫腳本/root/bin/links.sh,顯示正在連接本主機的每個遠程主機的IPV4地址和連接數,並按連接輸從大到小排序
#!/bin/bash
#
echo -e "lianjie: \n\tlianjieshu\tip"
netstat -nt |tr -s ' '|cut -d' ' -f5| tr -cs '0-9.' '\n'|egrep '([0-9]+.){3}[0-9]+'|sort|uniq -c|sort -nr|tr -s ' ' '\t'

 

環境變量;
        變量聲明、賦值
        export name=值      輸出 名稱 值
        declare -x name=值  聲明 選項 名稱 值
變量引用: $name,${name}
顯示所有的環境變量:
                  export
                  env
                  printenv
                  銷燬 : unset name
 bash中有許多內建的環境變量:PATH,SHELL,USRE,UID,HISTSIZE,HOME,PWD,OLDPWD,HISTFILE,PS1
 


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

位置變量:在腳本代碼中調用通過命令傳遞給腳本的參數
             $1,$2,$3...   對應調用第1.第2第3等參數
             $0  表示命令本身
             $*  傳遞給腳本的所有參數,全部參數何爲一個字符串
             $@  引用傳遞給腳本的所有參數,每個參數爲獨立字符串
             $#  傳遞給腳本參數的個數,
             $@ $* 只有在被雙引號包起來時候纔會有差異
        
bash中的算數運算:help let
                 +,-,*,/,% 取模式(取值)**(乘方)
                實現算數運算:
                1 let var=算數表達式
                2 var =$[算數表達式]      ]# number=$[2**3]     ~]# echo $number
                3 var =$((算數表達式))   ~]# number=$((2**3))   ~]# echo $number
                4 var =$(expr表達式 arg1 arg2 arg3...) 如A=$(expr $B \* $C)
                5 declare -i var = 數值
                6 echo  '算數表達式' | bc
                注意:*乘法符號有些場景中需要轉義
                bash有內建的隨機數生成器:$RANDOM(1-32767)
                echo $[$RANDOM%50]  表示0-49之間的隨機數
                echo $[$RANDOM%50+2] 表示1-50之間的隨機數
增強型賦值:
          +=,-=,*=,/=,%=
          使用方法:let var+=5    var值就是5
          自增,自減
          let var+=5      var=5
          let var++       在原有的數值上面加上1 比如原先設定的是5執行一次let var++就相當於加上數值1     
          let var-=1      在原有的數值上面減去1個數值
          let var--       在原有的數值上面減去1個數值

練習
5 寫一個腳本/root/bin/sumid.sh,計算/etc/passwd文件中的第10個用戶和第20個用戶之和
~]# vim sumdi.sh
#!/bin/bash
#
uid1=`sed -n '10p' /etc/passwd | cut -d: -f3`
uid2=`sed -n '20p' /etc/passwd | cut -d: -f3`
let sumid=$uid1+$uid2

echo -e "The 10 user ID is $uid1 ;\nthe 20 user ID is $uid2 ;\n\tthe sum of two users ID is $sumid ."
 
保存退出 chmod +x sumid.sh 加上執行權限

6寫一個腳本/root/bin/sumfile.sh,統計/etc, /var, /usr目錄中共有多少個一級子目錄和文件
~]# vim sumfile.sh
#!/bin/bash
#
file1=`ls -A /etc | wc -l`
file2=`ls -A /var | wc -l`
file3=`ls -A /usr | wc -l`
let sumfile=$file1+$file2+$file3
echo "$sumfile"


邏輯運算
在shell編程當中支持一些邏輯運算:    true1 真爲1 false0 假爲0
                               與運算:
                                     1與1=1  1&&1=1    1和任何數相與 是原值  1和1相與爲原來的值1
                                     1與0=0  1&&0=0    0和任何數相與 是0     1和0相與爲原來的值0
                                     0與1=0  0&&1=0    0和1相與 等0
                                     0與0=0  0&&0=0
                               或運算:
                                     1或1=1   1||1=1    只要有一個是真結果就爲真,      
                                     1或0=1   1||0=1           只要兩個都是假結果就爲假,
                                     0或1=1   0||1=1      
                                     0或0=0   0||0=0
                               非運算:
                                     !1=0     非真 則爲假
                                     !0=1     非假 則爲真
短路運算:
        短路與:
               第一個爲0, 結果必定爲0             命令1與命令2
               第一個爲1,第二個必須要參與運算      假0    假0   如果命令1成功將執行2
                                                           如果命令1失敗,將不執行命令2
       短路或:
              第一個爲1,結果必定爲1              命令1命令2    如果命令1執行成功將不執行命令2
              第一個爲0,第二個必須要參與運算      真1   真1    如果命令1執行不能功執行命令2
         異或:^
             異或的兩個值,相同爲假,不同爲真        ‘異性相吸 ,同性爲假’  兩個值相同爲假,不相同則爲真
     
兩種聚集命令的方法:
                  複合式:date; who| wc -l
                          命令會一個接一個地運行   順序執行,從左往右生效
        
                 子shell:(date;who | wc -l)>> /tmp/tarce
                          可以執行單個體命令
                          (date; who)| wc -l可以先執行括號裏面的命令

退出狀態進程使用退出狀態來報告成功或失敗
                 0  表示成功 ,1-255 代表失敗
                 $? 變量保存最近的命令退出狀態
                    例如 echo $?  可以查看上一條命令是否成功或失敗

自定義退出狀態碼: exit
                 注意:
                     1 腳本中一旦遇到exit命令,腳本會立即終止;終止退出狀態取決於exit命令後面的數字
                     2 如果未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決於腳本中執行的最後一條命令的狀態碼
     
條件測試:
        判斷某需求是否滿足,需要有測試機制來實現;
        專用的測試表達式需要有測試命令輔助完成測試過程;
        若真,返回的是0
        若假,返回的是1 
        測試命令:
                test 表達式          $w = $r
                test [表達式]  ]   [ $w = $r ]
                test [[表達式]] ] [[ $w = $r ]]
        注意:表達式 前後必須有空白字符
條件性的執行操作符:
 根據退出狀態而定,命令可以有條件地運行
命令1 && 命令2  短路與, 命令1成功,將執行命令2    ,如果命令1失敗,將不執行命令2
命令1 || 命令2  短路或, 命令1成功,將不執行命令2 ,如果命令1失敗,將執行命令2

 

bash 的測試類型
       數值測試:
              -gt  是否大於          
              -ge  是否大於等於
              -eq  是否等於
              -ne  是否不等於
              -lt  是否小於
              -le  是否小於等於
       字符串測試:
               ==  是否等於
               >   是否大於
               <   是否小於
               !=   是否不等於
               =~    左側字符串是否能夠被右側的表達式所匹配
                  注意;此表達式一般用於` `
               -z 字符串      字符串是否爲空,空爲真、不空爲假
               -n 字符串      字符串是否不空, 不空爲真,空爲假
               注意:用於字符串比較時的用到的操作數都應該使用引號

 

文件測試  :
        存在性測試:
                 -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     文件描述符是否已經打開並且與某終端相關
            -N file   文件上一次杜宇之後是否被修改過           
            -O file   當前有效用戶是否爲文件屬主
            -G file   當前有效用戶是否爲文件屬組
    雙目測試::
      file1 -ef file2       文件1和文件2 是否指定向同一個設備上的相同inode 是否爲同一個文件
      file1 -nt file2       文件1是否新於文件2
      file1 -ot file2       文件1是否舊與文件2             
 組合測試條件:
       第一種方式:
         命令1 && 命令2  並且
         命令1 || 命令2  或者
         !命令     非
         例如 [ -e file ] && [ -r file ]               
        第二種方式:
           表達式1 -a 表達式2  並且
           表達式1 -o 表達式2  或者
           !表達式   非
                 
                
練習
編寫腳本/root/bin/nologin.sh和login.sh,實現禁止和允許普通用戶登錄系統。
#!/bin/bash
#
[ -f /etc/nologin ] && echo "user disable login already" || (touch /etc/nologin; echo user disable login )               
   禁止普通用戶登錄             
#!/bin/bash
#
[ -f /etc/nologin ] && (rm -f /etc/nologin;echo user enable login) ||  echo user disable login already             
   允許普通用戶登錄            
                

計算1+2+3+...+100的值                
#!/bin/bash
#
shuzi=`echo {1..100}|tr ' ' '+'| bc`
echo $shuzi                

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