shell腳本編程

一、編程基礎:

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

shell腳本的用途有:

  • 自動化常用命令

  • 執行系統管理和故障排除

  • 創建簡單的應用程序

  • 處理文本或文件


1)     第一步:使用文本編輯器來創建文本文件 script.sh 並編寫內容

格式要求:首行shebang    指明所要使用的shell類型

#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl

結合命令、變量、表達式、語句等編寫腳本內容

“#”號開頭的行爲註釋行

#echo something
echo "test txte"

   

2)     第二步:運行腳本

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

]#chmod +x script.sh
]#./script.sh

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

]#bash script.sh

    #bash:調試執行腳本

        -n    簡單檢查腳本語法錯誤

        -x    調試執行,顯示腳本運行過程




二、變量:


變量類型:


1)本地變量:作用域僅爲當前shell進程

變量的定義:

    用戶定義的變量有字母數字及下劃線組成,

    變量名的第一個字符不能爲數字.

    變量名是大小寫敏感的


變量的引用:

    ${name},$name

    " ": 雙引號 變量名會替換爲其值
    ' ' :單引號 變量名不會替換

    查看變量:set
    撤銷變量:unset name


2)環境變量:作用域爲當前變量及其子進程 對其他登錄用戶無效


變量賦值:
   export name=value
   declare -x name=value
  
bash內嵌了很多環境變量(一般爲全大寫),用於定義bash工作環境

    PATH,HISTFILE,HISTSIZE,SHELL,HOME,UID,OLDPWD
    查看環境變量:export;declare -x;printenv;env
    撤銷環境變量:unset name


3)局部變量:作用域爲某代碼片段 函數上下文


4)只讀變量(常量)
  declare -r name
  readonly name
   只讀變量無法重新設定,不支持撤銷,當前shell終止後撤銷


5)特殊變量

    $0 腳本文件路徑本身 basename
    $#:參數個數
    $*:所有參數  "chen he zhao"  所有參數合併爲單個字符串
    $@:所有參數  "chen" "he" "zhao" 


    位置變量:

向腳本傳遞位置參數變量:
  scrip.sh argu1 argu2

對應
  $1,$2...${10},${11}...
  

輪替:
   shift#   去掉前#個參數   即${#+1}變成$1



數據類型:字符型,數值型



三、數值運算:

算術運算: + - * / % ^   *乘法有時需要轉義
  let var=expr
    $[expr]
    $((expr))
    $(expr argu1 argu2 argu3


 增強型賦值:
    let
        i+=#    :i=$i+#
        i-=
        i*=
        i/=
        i%=
   自增/自減:
     let VAR=$($VAR+1)
     let VAR+=1
     let VAR++
      --

]#i=1
]#let i++
]#echo $i
]#2
]#let i+=2
]#echo $i
]#4
]#expr 3 + 4]#expr 3 \* 4]#echo 3*4|bc




四、邏輯運算:

    運算數:真(true,yes,on,1)

     假(false,no,off,0)


1.與

1 && 1 = 1

1 && 0 = 0

0 && 1 = 0

0 && 0 = 0

2.或

1 || 1 = 1

1 || 0 = 1

0 || 1 = 1

0 || 0 = 0

3.非

! 1 = 0

! 0 = 1

4.異或

真真 假

真假 真

1)CMD1 && CMD2    如果真...就...

CMD1爲假 則CMD2不運行

CMD1爲真 則CMD2運行


2)CMD1 || CMD2    如果假...就...

CMD1爲真 則CMD2不運行

CMD1爲假 則CMD2運行


五、bash測試類型:

測試表達式:

test EXPRESSION

[ EXPRESSION ]  表達式兩端須有空格

    ` EXPRESSION `



    1.數值測試:  [ $num1 -## $num2 ]   整數測試!

-eq:等於

-ne:不等於

-gt:大於

-ge:大於等於

-lt:小於

-le:小於等於

]#[ 5 -gt 4 ]&&echo 0
]#0


2.字符串測試: [[ "CHAR" # "CHAR" ]] ASCLL碼比較

==:是否等於

>: 大於  ascll 編碼

<: 小於

!=:不等於

=~:左側字符串 是否能夠被右側 模式匹配 

  *   -z "STRING":判斷變量是否爲空;空位真,不空爲假

-n "STRING":判斷是否不空 空爲假,不空爲真

]#[[ root =~ r.*t ]]&&echo 0
]#0


3.文件測試:

 存在性測試:

-a FILE

-e FILE

存在爲真

 文件類型測試: [ -# /PATH/FILE ]

-b 存在且爲 塊設備

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

-d 存在且爲 目錄

-f 存在且爲 普通文件

-p 存在且爲 管道文件

-S 存在且爲 套接字文件

-h|L  存在且爲 符號鏈接文件

]#[ -d /etc ] && echo 0

]#0


4.文件權限測試:   以用戶 實際權限;   root用戶存在特權

      000  但對root可讀 可寫 不可執行

-r 存在且 對當前用戶可讀

-w 存在且 對當前用戶可寫

-x 存在且 對對當前用戶可執行

 -特殊權限測試:

-u 存在且有 suid

-g 存在且有 sgid

-k 存在且有 stick

 -文件是否非空:

* -s 不空爲真,空爲假

 -時間戳:

-N 文件自最近被讀後是否被修改過

 -從屬關係測試:

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

-G 當前用戶是否 屬於文件屬組

 -雙目測試: mtime 判斷修改時間

FILE1 -ef FILE2 是否互爲硬鏈接

* FILE1 -nt FILE2 F1是否新於F2

FILE1 -ot FILE2 F1是否舊於F2


-a = 且

-o = 或

]#a=6
]#[ $a -gt 0 -a $a -lt 9 ] && echo 0
]#0



六、腳本的狀態返回值:

默認腳本執行的最後一條命令的狀態返回值;

自定義狀態退出狀態碼;

exit [n]:     n 對應 $? 的值

        shell進程遇到exit 即結束  n=[0-255]


    利用命令狀態返回值判斷:

0:成功

1-255:失敗



#read [OPTION]   獲取用戶輸入信息,從而完成變量賦值

-p ""設置提示信息

-t # 設置超時時間

]#read -p "please enter a number:" num
]#please enter a number:5
]#echo $num
]#5



====作業

一、腳本

1、編寫腳本/root/bin/systeminfo.sh,顯示當前主機系統信息,包括主機名,IPv4地址,操作系統版本,內核版本,CPU型號,內存大小,硬盤大小。

#!/bin/bash
printf %-10s "hostname:"
echo "`hostname`"
printf %-10s "ip:"
echo  "`ifconfig|sed -nr 's/.*r:(.*) B.*/\1/p'`"
printf %-10s "kernel:"
echo  "`uname -r|tr ':' ':\t'`"
printf %-10s "OS:"
echo  "OS:\t\t`cat /etc/redhat-release`"
printf %-10s "CPU:"
echo  "`lscpu|grep "Model name"|tr -d " "|cut -d: -f2`"
printf %-10s "Mem:"
echo  "free|sed -n 2p|tr -s ' '|cut -d' ' -f2"
printf %-10s "DiskSize:"
echo  "`lsblk|sed -n 2p|tr -s " "|cut -d " " -f4`"


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

#!/bin/bash
cp -a /etc /testdir/etc$(date +%F)&>/dev/null&&echo cp success||echo cp failuer


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

#!/bin/bash
echo "the max usage:`df|grep '/dev/sd.*'|tr -s ' '|cut -d' ' -f5|sort|tail -1`"

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

#!/bin/bash
netstat -t|tr -s ' ' ':'|cut -d: -f6|grep [0-9]|sort|uniq -c|sort -nr


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

!/bin/bash
ID1=`sed -n ${1}p /etc/passwd|cut -d: -f3`
ID2=`sed -n ${2}p /etc/passwd|cut -d: -f3`
let sum=ID1+ID2
echo "sum:$sum"


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

#!/bin/bash
blank1=`grep "^$" $1|wc -l`
blank2=`grep "^$" $2|wc -l`
let sum=blank1+blank2
echo "sum=$sum"


7、寫一個腳本/root/bin/sumfile.sh,統計/etc, /var, /usr目錄中共有多少個一級子目錄和文件

#!/bin/bash
s1=`ls /etc|wc -l`
s2=`ls /var|wc -l`
s3=`ls /usr|wc -l`
sum=$[s1+s2+s3]
echo "sum=$sum"


8、寫一個腳本/root/bin/argsnum.sh,接受一個文件路徑作爲參數;如果參數個數小於1,則提示用戶“至少應該給一個參數”,並立即退出;如果參數個數不小於1,則顯示第一個參數所指向的文件中的空白行數

#!/bin/bash
echo -n "please enter a path:"
read path
[ ! -e $path ] &&  echo "file does not exist" && exit 5 || grep -c "^[[:space:]]*$" $path
#[[ $# -lt 1 ]] && echo "at least one arg" && exit 5 || grep -c "^[[:space:]]*$" $1


9、寫一個腳本/root/bin/hostping.sh,接受一個主機的IPv4地址做爲參數,測試是否可連通。如果能ping通,則提示用戶“該IP地址可訪問”;如果不可ping通,則提示用戶“該IP地址不可訪問”

#!/bin/bash
read -p "please ernter a ip adddress:" addr
ping $addr -W1 -c1&>/dev/null && echo "IP address rechable!" || echo "IPaddress unrechable!"


10、判斷硬盤的每個分區空間和inode的利用率是否大於80,如果是,發郵件通知root磁盤滿

#!/bin/bash
disk=`df |grep "/dev/sd.*"|cut -c 44-46|sort -nr|head -1`
inode=`df -i|grep "/dev/sd.*"|cut -c 40-42|sort -nr|head -1`
[ $disk -gt 80 -o $inode -gt 80 ]&&echo 'disk fulling'|mail root||echo dont worry


11、指定文件做爲參數,判斷文件是否爲.sh後綴,如果是,添加x權限

#!/bin/bash
[ ! -e $1 ]&&echo "file dose not exist!"&&exit 23
[[ $1 =~ .*\.sh$ ]]&&chmod +x $1&&echo '+x done'||echo not sh


12、判斷輸入的IP是否爲合法IP

#!/bin/bash
echo -n "please enter a ip:"
read ip
echo  $ip|egrep -q "^(\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>\.){3}(\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>)$" && echo legal ip || echo illegal ip

13、計算1+2+3+...+100

#!/bin/bash
seq -s '+' 1 100|bc


14、輸入起始值A和最後值B,計算從A+(A+1)...+(B-1)+B的總和

#!/bin/bash
seq -s '+' $1 $2|bc








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